r341641 - [MSan] add KMSAN support to Clang driver
Author: glider Date: Fri Sep 7 02:21:09 2018 New Revision: 341641 URL: http://llvm.org/viewvc/llvm-project?rev=341641&view=rev Log: [MSan] add KMSAN support to Clang driver Boilerplate code for using KMSAN instrumentation in Clang. We add a new command line flag, -fsanitize=kernel-memory, with a corresponding SanitizerKind::KernelMemory, which, along with SanitizerKind::Memory, maps to the memory_sanitizer feature. KMSAN is only supported on x86_64 Linux. It's incompatible with other sanitizers, but supports code coverage instrumentation. Modified: cfe/trunk/include/clang/Basic/Features.def cfe/trunk/include/clang/Basic/Sanitizers.def cfe/trunk/lib/CodeGen/BackendUtil.cpp cfe/trunk/lib/CodeGen/CGDeclCXX.cpp cfe/trunk/lib/CodeGen/CodeGenFunction.cpp cfe/trunk/lib/Driver/SanitizerArgs.cpp cfe/trunk/lib/Driver/ToolChains/Linux.cpp cfe/trunk/lib/Frontend/CompilerInvocation.cpp cfe/trunk/test/CodeGen/cleanup-destslot-simple.c cfe/trunk/test/Driver/fsanitize-coverage.c cfe/trunk/test/Driver/fsanitize.c cfe/trunk/test/Driver/msan.c cfe/trunk/test/Lexer/has_feature_memory_sanitizer.cpp Modified: cfe/trunk/include/clang/Basic/Features.def URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Features.def?rev=341641&r1=341640&r2=341641&view=diff == --- cfe/trunk/include/clang/Basic/Features.def (original) +++ cfe/trunk/include/clang/Basic/Features.def Fri Sep 7 02:21:09 2018 @@ -72,7 +72,9 @@ FEATURE(cxx_rtti, LangOpts.RTTI &&LangOp FEATURE(enumerator_attributes, true) FEATURE(nullability, true) FEATURE(nullability_on_arrays, true) -FEATURE(memory_sanitizer, LangOpts.Sanitize.has(SanitizerKind::Memory)) +FEATURE(memory_sanitizer, +LangOpts.Sanitize.hasOneOf(SanitizerKind::Memory | + SanitizerKind::KernelMemory)) FEATURE(thread_sanitizer, LangOpts.Sanitize.has(SanitizerKind::Thread)) FEATURE(dataflow_sanitizer, LangOpts.Sanitize.has(SanitizerKind::DataFlow)) FEATURE(efficiency_sanitizer, Modified: cfe/trunk/include/clang/Basic/Sanitizers.def URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Sanitizers.def?rev=341641&r1=341640&r2=341641&view=diff == --- cfe/trunk/include/clang/Basic/Sanitizers.def (original) +++ cfe/trunk/include/clang/Basic/Sanitizers.def Fri Sep 7 02:21:09 2018 @@ -53,6 +53,9 @@ SANITIZER("kernel-hwaddress", KernelHWAd // MemorySanitizer SANITIZER("memory", Memory) +// Kernel MemorySanitizer (KMSAN) +SANITIZER("kernel-memory", KernelMemory) + // libFuzzer SANITIZER("fuzzer", Fuzzer) Modified: cfe/trunk/lib/CodeGen/BackendUtil.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/BackendUtil.cpp?rev=341641&r1=341640&r2=341641&view=diff == --- cfe/trunk/lib/CodeGen/BackendUtil.cpp (original) +++ cfe/trunk/lib/CodeGen/BackendUtil.cpp Fri Sep 7 02:21:09 2018 @@ -265,14 +265,15 @@ static void addKernelHWAddressSanitizerP /*CompileKernel*/ true, /*Recover*/ true)); } -static void addMemorySanitizerPass(const PassManagerBuilder &Builder, - legacy::PassManagerBase &PM) { +static void addGeneralOptsForMemorySanitizer(const PassManagerBuilder &Builder, + legacy::PassManagerBase &PM, + bool CompileKernel) { const PassManagerBuilderWrapper &BuilderWrapper = static_cast(Builder); const CodeGenOptions &CGOpts = BuilderWrapper.getCGOpts(); int TrackOrigins = CGOpts.SanitizeMemoryTrackOrigins; bool Recover = CGOpts.SanitizeRecover.has(SanitizerKind::Memory); - PM.add(createMemorySanitizerPass(TrackOrigins, Recover)); + PM.add(createMemorySanitizerPass(TrackOrigins, Recover, CompileKernel)); // MemorySanitizer inserts complex instrumentation that mostly follows // the logic of the original code, but operates on "shadow" values. @@ -287,6 +288,16 @@ static void addMemorySanitizerPass(const } } +static void addMemorySanitizerPass(const PassManagerBuilder &Builder, + legacy::PassManagerBase &PM) { + addGeneralOptsForMemorySanitizer(Builder, PM, /*CompileKernel*/ false); +} + +static void addKernelMemorySanitizerPass(const PassManagerBuilder &Builder, + legacy::PassManagerBase &PM) { + addGeneralOptsForMemorySanitizer(Builder, PM, /*CompileKernel*/ true); +} + static void addThreadSanitizerPass(const PassManagerBuilder &Builder, legacy::PassManagerBase &PM) { PM.add(createThreadSanitizerPass()); @@ -614,6 +625,13 @@ void EmitAssemblyHelper::CreatePasses(le addMemorySanitizerPass); } + if (LangOpts.Sanitize.has(S
r304984 - [sanitizer-coverage] Allow using KASAN instrumentation with sancov
Author: glider Date: Thu Jun 8 11:24:21 2017 New Revision: 304984 URL: http://llvm.org/viewvc/llvm-project?rev=304984&view=rev Log: [sanitizer-coverage] Allow using KASAN instrumentation with sancov Modified: cfe/trunk/lib/Driver/SanitizerArgs.cpp cfe/trunk/test/Driver/fsanitize-coverage.c Modified: cfe/trunk/lib/Driver/SanitizerArgs.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/SanitizerArgs.cpp?rev=304984&r1=304983&r2=304984&view=diff == --- cfe/trunk/lib/Driver/SanitizerArgs.cpp (original) +++ cfe/trunk/lib/Driver/SanitizerArgs.cpp Thu Jun 8 11:24:21 2017 @@ -31,8 +31,8 @@ enum : SanitizerMask { NotAllowedWithTrap = Vptr, RequiresPIE = DataFlow, NeedsUnwindTables = Address | Thread | Memory | DataFlow, - SupportsCoverage = - Address | Memory | Leak | Undefined | Integer | Nullability | DataFlow, + SupportsCoverage = Address | KernelAddress | Memory | Leak | Undefined | + Integer | Nullability | DataFlow, RecoverableByDefault = Undefined | Integer | Nullability, Unrecoverable = Unreachable | Return, LegacyFsanitizeRecoverMask = Undefined | Integer, Modified: cfe/trunk/test/Driver/fsanitize-coverage.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Driver/fsanitize-coverage.c?rev=304984&r1=304983&r2=304984&view=diff == --- cfe/trunk/test/Driver/fsanitize-coverage.c (original) +++ cfe/trunk/test/Driver/fsanitize-coverage.c Thu Jun 8 11:24:21 2017 @@ -5,6 +5,7 @@ // CHECK-SANITIZE-COVERAGE-0: -fsanitize=address // RUN: %clang -target x86_64-linux-gnu -fsanitize=address -fsanitize-coverage=func,trace-pc %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANITIZE-COVERAGE-FUNC +// RUN: %clang -target x86_64-linux-gnu -fsanitize=kernel-address -fsanitize-coverage=func,trace-pc %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANITIZE-COVERAGE-FUNC // RUN: %clang -target x86_64-linux-gnu -fsanitize=memory -fsanitize-coverage=func,trace-pc %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANITIZE-COVERAGE-FUNC // RUN: %clang -target x86_64-linux-gnu -fsanitize=leak -fsanitize-coverage=func,trace-pc %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANITIZE-COVERAGE-FUNC // RUN: %clang -target x86_64-linux-gnu -fsanitize=undefined -fsanitize-coverage=func,trace-pc %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANITIZE-COVERAGE-FUNC ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r354861 - CodeGen: Explicitly initialize structure padding in the -ftrivial-auto-var-init mode
Author: glider Date: Tue Feb 26 02:46:21 2019 New Revision: 354861 URL: http://llvm.org/viewvc/llvm-project?rev=354861&view=rev Log: CodeGen: Explicitly initialize structure padding in the -ftrivial-auto-var-init mode When generating initializers for local structures in the -ftrivial-auto-var-init mode, explicitly wipe the padding bytes with either 0x00 or 0xAA. This will allow us to automatically handle the padding when splitting the initialization stores (see https://reviews.llvm.org/D57898). Reviewed at https://reviews.llvm.org/D58188 Modified: cfe/trunk/lib/CodeGen/CGDecl.cpp cfe/trunk/test/CodeGenCXX/auto-var-init.cpp Modified: cfe/trunk/lib/CodeGen/CGDecl.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDecl.cpp?rev=354861&r1=354860&r2=354861&view=diff == --- cfe/trunk/lib/CodeGen/CGDecl.cpp (original) +++ cfe/trunk/lib/CodeGen/CGDecl.cpp Tue Feb 26 02:46:21 2019 @@ -1048,6 +1048,98 @@ static llvm::Constant *patternFor(CodeGe return llvm::ConstantStruct::get(StructTy, Struct); } +enum class IsPattern { No, Yes }; + +/// Generate a constant filled with either a pattern or zeroes. +static llvm::Constant *patternOrZeroFor(CodeGenModule &CGM, IsPattern isPattern, +llvm::Type *Ty) { + if (isPattern == IsPattern::Yes) +return patternFor(CGM, Ty); + else +return llvm::Constant::getNullValue(Ty); +} + +static llvm::Constant *constWithPadding(CodeGenModule &CGM, IsPattern isPattern, +llvm::Constant *constant); + +/// Helper function for constWithPadding() to deal with padding in structures. +static llvm::Constant *constStructWithPadding(CodeGenModule &CGM, + IsPattern isPattern, + llvm::StructType *STy, + llvm::Constant *constant) { + const llvm::DataLayout &DL = CGM.getDataLayout(); + const llvm::StructLayout *Layout = DL.getStructLayout(STy); + llvm::Type *Int8Ty = llvm::IntegerType::getInt8Ty(CGM.getLLVMContext()); + unsigned SizeSoFar = 0; + SmallVector Values; + bool NestedIntact = true; + for (unsigned i = 0, e = STy->getNumElements(); i != e; i++) { +unsigned CurOff = Layout->getElementOffset(i); +if (SizeSoFar < CurOff) { + assert(!STy->isPacked()); + auto *PadTy = llvm::ArrayType::get(Int8Ty, CurOff - SizeSoFar); + Values.push_back(patternOrZeroFor(CGM, isPattern, PadTy)); +} +llvm::Constant *CurOp; +if (constant->isZeroValue()) + CurOp = llvm::Constant::getNullValue(STy->getElementType(i)); +else + CurOp = cast(constant->getAggregateElement(i)); +auto *NewOp = constWithPadding(CGM, isPattern, CurOp); +if (CurOp != NewOp) + NestedIntact = false; +Values.push_back(NewOp); +SizeSoFar = CurOff + DL.getTypeAllocSize(CurOp->getType()); + } + unsigned TotalSize = Layout->getSizeInBytes(); + if (SizeSoFar < TotalSize) { +auto *PadTy = llvm::ArrayType::get(Int8Ty, TotalSize - SizeSoFar); +Values.push_back(patternOrZeroFor(CGM, isPattern, PadTy)); + } + if (NestedIntact && Values.size() == STy->getNumElements()) +return constant; + return llvm::ConstantStruct::getAnon(Values); +} + +/// Replace all padding bytes in a given constant with either a pattern byte or +/// 0x00. +static llvm::Constant *constWithPadding(CodeGenModule &CGM, IsPattern isPattern, +llvm::Constant *constant) { + llvm::Type *OrigTy = constant->getType(); + if (const auto STy = dyn_cast(OrigTy)) +return constStructWithPadding(CGM, isPattern, STy, constant); + if (auto *STy = dyn_cast(OrigTy)) { +llvm::SmallVector Values; +unsigned Size = STy->getNumElements(); +if (!Size) + return constant; +llvm::Type *ElemTy = STy->getElementType(); +bool ZeroInitializer = constant->isZeroValue(); +llvm::Constant *OpValue, *PaddedOp; +if (ZeroInitializer) { + OpValue = llvm::Constant::getNullValue(ElemTy); + PaddedOp = constWithPadding(CGM, isPattern, OpValue); +} +for (unsigned Op = 0; Op != Size; ++Op) { + if (!ZeroInitializer) { +OpValue = constant->getAggregateElement(Op); +PaddedOp = constWithPadding(CGM, isPattern, OpValue); + } + Values.push_back(PaddedOp); +} +auto *NewElemTy = Values[0]->getType(); +if (NewElemTy == ElemTy) + return constant; +if (OrigTy->isArrayTy()) { + auto *ArrayTy = llvm::ArrayType::get(NewElemTy, Size); + return llvm::ConstantArray::get(ArrayTy, Values); +} else { + return llvm::ConstantVector::get(Values); +} + } + return constant; +} + static Address createUnnamedGlobalFrom(CodeGenModule &CGM, const VarDecl &D, CGBuilderTy &Builder, llvm:
r355181 - CodeGen: Fix PR40605 by splitting constant struct initializers
Author: glider Date: Fri Mar 1 01:00:41 2019 New Revision: 355181 URL: http://llvm.org/viewvc/llvm-project?rev=355181&view=rev Log: CodeGen: Fix PR40605 by splitting constant struct initializers When emitting initializers for local structures for code built with -ftrivial-auto-var-init, replace constant structures with sequences of stores. This appears to greatly help removing dead initialization stores to those locals that are later overwritten by other data. This also removes a lot of .rodata constants (see PR40605), replacing most of them with immediate values (for Linux kernel the .rodata size is reduced by ~1.9%) Modified: cfe/trunk/lib/CodeGen/CGDecl.cpp cfe/trunk/test/CodeGenCXX/auto-var-init.cpp Modified: cfe/trunk/lib/CodeGen/CGDecl.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDecl.cpp?rev=355181&r1=355180&r2=355181&view=diff == --- cfe/trunk/lib/CodeGen/CGDecl.cpp (original) +++ cfe/trunk/lib/CodeGen/CGDecl.cpp Fri Mar 1 01:00:41 2019 @@ -969,6 +969,20 @@ static llvm::Value *shouldUseMemSetToIni return llvm::isBytewiseValue(Init); } +/// Decide whether we want to split a constant structure store into a sequence +/// of its fields' stores. This may cost us code size and compilation speed, +/// but plays better with store optimizations. +static bool shouldSplitStructStore(CodeGenModule &CGM, + uint64_t GlobalByteSize) { + // Don't break structures that occupy more than one cacheline. + uint64_t ByteSizeLimit = 64; + if (CGM.getCodeGenOpts().OptimizationLevel == 0) +return false; + if (GlobalByteSize <= ByteSizeLimit) +return true; + return false; +} + static llvm::Constant *patternFor(CodeGenModule &CGM, llvm::Type *Ty) { // The following value is a guaranteed unmappable pointer value and has a // repeated byte-pattern which makes it easier to synthesize. We use it for @@ -1201,6 +1215,8 @@ static void emitStoresForConstant(CodeGe // If the initializer is all or mostly the same, codegen with bzero / memset // then do a few stores afterward. uint64_t ConstantSize = CGM.getDataLayout().getTypeAllocSize(Ty); + if (!ConstantSize) +return; auto *SizeVal = llvm::ConstantInt::get(IntPtrTy, ConstantSize); if (shouldUseBZeroPlusStoresToInitialize(constant, ConstantSize)) { Builder.CreateMemSet(Loc, llvm::ConstantInt::get(Int8Ty, 0), SizeVal, @@ -1228,6 +1244,20 @@ static void emitStoresForConstant(CodeGe return; } + llvm::StructType *STy = dyn_cast(Ty); + // FIXME: handle the case when STy != Loc.getElementType(). + // FIXME: handle non-struct aggregate types. + if (STy && (STy == Loc.getElementType()) && + shouldSplitStructStore(CGM, ConstantSize)) { +for (unsigned i = 0; i != constant->getNumOperands(); i++) { + Address EltPtr = Builder.CreateStructGEP(Loc, i); + emitStoresForConstant( + CGM, D, EltPtr, isVolatile, Builder, + cast(Builder.CreateExtractValue(constant, i))); +} +return; + } + Builder.CreateMemCpy( Loc, createUnnamedGlobalFrom(CGM, D, Builder, constant, Loc.getAlignment()), Modified: cfe/trunk/test/CodeGenCXX/auto-var-init.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/auto-var-init.cpp?rev=355181&r1=355180&r2=355181&view=diff == --- cfe/trunk/test/CodeGenCXX/auto-var-init.cpp (original) +++ cfe/trunk/test/CodeGenCXX/auto-var-init.cpp Fri Mar 1 01:00:41 2019 @@ -1,6 +1,8 @@ -// RUN: %clang_cc1 -std=c++14 -triple x86_64-unknown-unknown -fblocks %s -emit-llvm -o - | FileCheck %s -// RUN: %clang_cc1 -std=c++14 -triple x86_64-unknown-unknown -fblocks -ftrivial-auto-var-init=pattern %s -emit-llvm -o - | FileCheck %s -check-prefix=PATTERN -// RUN: %clang_cc1 -std=c++14 -triple x86_64-unknown-unknown -fblocks -ftrivial-auto-var-init=zero %s -emit-llvm -o - | FileCheck %s -check-prefix=ZERO +// RUN: %clang_cc1 -std=c++14 -triple x86_64-unknown-unknown -fblocks %s -emit-llvm -o - | FileCheck %s -check-prefixes=CHECK,CHECK-O0 +// RUN: %clang_cc1 -std=c++14 -triple x86_64-unknown-unknown -fblocks -ftrivial-auto-var-init=pattern %s -emit-llvm -o - | FileCheck %s -check-prefixes=CHECK-O0,PATTERN,PATTERN-O0 +// RUN: %clang_cc1 -std=c++14 -triple x86_64-unknown-unknown -fblocks -ftrivial-auto-var-init=pattern %s -O1 -emit-llvm -o - | FileCheck %s -check-prefixes=CHECK-O1,PATTERN,PATTERN-O1 +// RUN: %clang_cc1 -std=c++14 -triple x86_64-unknown-unknown -fblocks -ftrivial-auto-var-init=zero %s -emit-llvm -o - | FileCheck %s -check-prefixes=CHECK-O0,ZERO,ZERO-O0 +// RUN: %clang_cc1 -std=c++14 -triple x86_64-unknown-unknown -fblocks -ftrivial-auto-var-init=zero %s -O1 -emit-llvm -o - | FileCheck %s -check-prefixes=CHECK-O1,ZERO,ZERO-O1 template void used(T &) noexcept; @@ -30,120 +32,192 @@ template void used(T &) noex
Re: [PATCH] D57898: [RFC] Split constant structures generated by -ftrivial-auto-var-init when emitting initializators
Still unsure about the heuristic here. I believe that for auto-initialization we want to be quite aggressive with these splits (unlike for regular constant stores). Perhaps we should do the split in the case all bytes are pattern bytes? (This is probably another use case for `forInit`) On Fri, Feb 8, 2019, 11:36 Alexander Potapenko via Phabricator < revi...@reviews.llvm.org> wrote: > glider marked 2 inline comments as not done. > glider added a comment. > > Sorry, didn't mean to mark these done. > > > CHANGES SINCE LAST ACTION > https://reviews.llvm.org/D57898/new/ > > https://reviews.llvm.org/D57898 > > > > ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [sanitizer][msan] fix AArch64 vararg support for KMSAN (PR #70659)
https://github.com/ramosian-glider created https://github.com/llvm/llvm-project/pull/70659 Cast StackSaveAreaPtr, GrRegSaveAreaPtr, VrRegSaveAreaPtr to pointers to fix assertions in getShadowOriginPtrKernel(). Fixes: https://github.com/llvm/llvm-project/issues/69738 Patch by Mark Johnston. >From 3be71f474ee11326567458c8145c3b4e56031189 Mon Sep 17 00:00:00 2001 From: Alexander Potapenko Date: Mon, 30 Oct 2023 12:18:47 +0100 Subject: [PATCH] [sanitizer][msan] fix AArch64 vararg support for KMSAN Cast StackSaveAreaPtr, GrRegSaveAreaPtr, VrRegSaveAreaPtr to pointers to fix assertions in getShadowOriginPtrKernel(). Fixes: https://github.com/llvm/llvm-project/issues/69738 Patch by Mark Johnston. --- .../Instrumentation/MemorySanitizer.cpp | 10 ++-- .../MemorySanitizer/AArch64/vararg-kmsan.ll | 51 +++ .../MemorySanitizer/X86/vararg.ll | 1 + 3 files changed, 59 insertions(+), 3 deletions(-) create mode 100644 llvm/test/Instrumentation/MemorySanitizer/AArch64/vararg-kmsan.ll diff --git a/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp b/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp index e72db2d9d770eef..315d7c96ec65390 100644 --- a/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp @@ -5258,21 +5258,25 @@ struct VarArgAArch64Helper : public VarArgHelper { // we need to adjust the offset for both GR and VR fields based on // the __{gr,vr}_offs value (since they are stores based on incoming // named arguments). + Type *RegSaveAreaPtrTy = IRB.getInt8PtrTy(); // Read the stack pointer from the va_list. - Value *StackSaveAreaPtr = getVAField64(IRB, VAListTag, 0); + Value *StackSaveAreaPtr = + IRB.CreateIntToPtr(getVAField64(IRB, VAListTag, 0), RegSaveAreaPtrTy); // Read both the __gr_top and __gr_off and add them up. Value *GrTopSaveAreaPtr = getVAField64(IRB, VAListTag, 8); Value *GrOffSaveArea = getVAField32(IRB, VAListTag, 24); - Value *GrRegSaveAreaPtr = IRB.CreateAdd(GrTopSaveAreaPtr, GrOffSaveArea); + Value *GrRegSaveAreaPtr = IRB.CreateIntToPtr( + IRB.CreateAdd(GrTopSaveAreaPtr, GrOffSaveArea), RegSaveAreaPtrTy); // Read both the __vr_top and __vr_off and add them up. Value *VrTopSaveAreaPtr = getVAField64(IRB, VAListTag, 16); Value *VrOffSaveArea = getVAField32(IRB, VAListTag, 28); - Value *VrRegSaveAreaPtr = IRB.CreateAdd(VrTopSaveAreaPtr, VrOffSaveArea); + Value *VrRegSaveAreaPtr = IRB.CreateIntToPtr( + IRB.CreateAdd(VrTopSaveAreaPtr, VrOffSaveArea), RegSaveAreaPtrTy); // It does not know how many named arguments is being used and, on the // callsite all the arguments were saved. Since __gr_off is defined as diff --git a/llvm/test/Instrumentation/MemorySanitizer/AArch64/vararg-kmsan.ll b/llvm/test/Instrumentation/MemorySanitizer/AArch64/vararg-kmsan.ll new file mode 100644 index 000..2189424cd76faaf --- /dev/null +++ b/llvm/test/Instrumentation/MemorySanitizer/AArch64/vararg-kmsan.ll @@ -0,0 +1,51 @@ +; RUN: opt < %s -S -passes=msan -msan-kernel=1 2>&1 | FileCheck %s + +target datalayout = "e-m:e-i64:64-i128:128-n32:64-S128" +target triple = "aarch64-unknown-linux-gnu" + +%struct.__va_list = type { ptr, ptr, ptr, i32, i32 } + +define i32 @foo(i32 %guard, ...) { + %vl = alloca %struct.__va_list, align 8 + call void @llvm.lifetime.start.p0(i64 32, ptr %vl) + call void @llvm.va_start(ptr %vl) + call void @llvm.va_end(ptr %vl) + call void @llvm.lifetime.end.p0(i64 32, ptr %vl) + ret i32 0 +} + +; First check if the variadic shadow values are saved in stack with correct +; size (192 is total of general purpose registers size, 64, plus total of +; floating-point registers size, 128). + +; CHECK-LABEL: @foo +; CHECK: [[A:%.*]] = load {{.*}} ptr %va_arg_overflow_size +; CHECK: [[B:%.*]] = add i64 192, [[A]] +; CHECK: alloca {{.*}} [[B]] + +; We expect three memcpy operations: one for the general purpose registers, +; one for floating-point/SIMD ones, and one for thre remaining arguments. + +; Propagate the GR shadow values on for the va_list::__gp_top, adjust the +; offset in the __msan_va_arg_tls based on va_list:__gp_off, and finally +; issue the memcpy. +; CHECK: [[GRP:%.*]] = getelementptr inbounds i8, ptr {{%.*}}, i64 {{%.*}} +; CHECK: [[GRSIZE:%.*]] = sub i64 64, {{%.*}} +; CHECK: call void @llvm.memcpy.p0.p0.i64(ptr align 8 {{%.*}}, ptr align 8 [[GRP]], i64 [[GRSIZE]], i1 false) + +; Propagate the VR shadow values on for the va_list::__vr_top, adjust the +; offset in the __msan_va_arg_tls based on va_list:__vr_off, and finally +; issue the memcpy. +; CHECK: [[VRP:%.*]] = getelementptr inbounds i8, ptr {{%.*}}, i64 {{%.*}} +; CHECK: [[VRSIZE:%.*]] = sub i64 128, {{%.*}} +; CHECK: call void @llvm.memcpy.p0.p0.i64(ptr align 8 {{%.*}}, ptr align 8 [[VRP]], i64 [[VRSIZE]], i1 false) + +; Copy the
[clang] [sanitizer][msan] fix AArch64 vararg support for KMSAN (PR #70659)
https://github.com/ramosian-glider created https://github.com/llvm/llvm-project/pull/70659 Cast StackSaveAreaPtr, GrRegSaveAreaPtr, VrRegSaveAreaPtr to pointers to fix assertions in getShadowOriginPtrKernel(). Fixes: https://github.com/llvm/llvm-project/issues/69738 Patch by Mark Johnston. >From 3be71f474ee11326567458c8145c3b4e56031189 Mon Sep 17 00:00:00 2001 From: Alexander Potapenko Date: Mon, 30 Oct 2023 12:18:47 +0100 Subject: [PATCH] [sanitizer][msan] fix AArch64 vararg support for KMSAN Cast StackSaveAreaPtr, GrRegSaveAreaPtr, VrRegSaveAreaPtr to pointers to fix assertions in getShadowOriginPtrKernel(). Fixes: https://github.com/llvm/llvm-project/issues/69738 Patch by Mark Johnston. --- .../Instrumentation/MemorySanitizer.cpp | 10 ++-- .../MemorySanitizer/AArch64/vararg-kmsan.ll | 51 +++ .../MemorySanitizer/X86/vararg.ll | 1 + 3 files changed, 59 insertions(+), 3 deletions(-) create mode 100644 llvm/test/Instrumentation/MemorySanitizer/AArch64/vararg-kmsan.ll diff --git a/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp b/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp index e72db2d9d770eef..315d7c96ec65390 100644 --- a/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp @@ -5258,21 +5258,25 @@ struct VarArgAArch64Helper : public VarArgHelper { // we need to adjust the offset for both GR and VR fields based on // the __{gr,vr}_offs value (since they are stores based on incoming // named arguments). + Type *RegSaveAreaPtrTy = IRB.getInt8PtrTy(); // Read the stack pointer from the va_list. - Value *StackSaveAreaPtr = getVAField64(IRB, VAListTag, 0); + Value *StackSaveAreaPtr = + IRB.CreateIntToPtr(getVAField64(IRB, VAListTag, 0), RegSaveAreaPtrTy); // Read both the __gr_top and __gr_off and add them up. Value *GrTopSaveAreaPtr = getVAField64(IRB, VAListTag, 8); Value *GrOffSaveArea = getVAField32(IRB, VAListTag, 24); - Value *GrRegSaveAreaPtr = IRB.CreateAdd(GrTopSaveAreaPtr, GrOffSaveArea); + Value *GrRegSaveAreaPtr = IRB.CreateIntToPtr( + IRB.CreateAdd(GrTopSaveAreaPtr, GrOffSaveArea), RegSaveAreaPtrTy); // Read both the __vr_top and __vr_off and add them up. Value *VrTopSaveAreaPtr = getVAField64(IRB, VAListTag, 16); Value *VrOffSaveArea = getVAField32(IRB, VAListTag, 28); - Value *VrRegSaveAreaPtr = IRB.CreateAdd(VrTopSaveAreaPtr, VrOffSaveArea); + Value *VrRegSaveAreaPtr = IRB.CreateIntToPtr( + IRB.CreateAdd(VrTopSaveAreaPtr, VrOffSaveArea), RegSaveAreaPtrTy); // It does not know how many named arguments is being used and, on the // callsite all the arguments were saved. Since __gr_off is defined as diff --git a/llvm/test/Instrumentation/MemorySanitizer/AArch64/vararg-kmsan.ll b/llvm/test/Instrumentation/MemorySanitizer/AArch64/vararg-kmsan.ll new file mode 100644 index 000..2189424cd76faaf --- /dev/null +++ b/llvm/test/Instrumentation/MemorySanitizer/AArch64/vararg-kmsan.ll @@ -0,0 +1,51 @@ +; RUN: opt < %s -S -passes=msan -msan-kernel=1 2>&1 | FileCheck %s + +target datalayout = "e-m:e-i64:64-i128:128-n32:64-S128" +target triple = "aarch64-unknown-linux-gnu" + +%struct.__va_list = type { ptr, ptr, ptr, i32, i32 } + +define i32 @foo(i32 %guard, ...) { + %vl = alloca %struct.__va_list, align 8 + call void @llvm.lifetime.start.p0(i64 32, ptr %vl) + call void @llvm.va_start(ptr %vl) + call void @llvm.va_end(ptr %vl) + call void @llvm.lifetime.end.p0(i64 32, ptr %vl) + ret i32 0 +} + +; First check if the variadic shadow values are saved in stack with correct +; size (192 is total of general purpose registers size, 64, plus total of +; floating-point registers size, 128). + +; CHECK-LABEL: @foo +; CHECK: [[A:%.*]] = load {{.*}} ptr %va_arg_overflow_size +; CHECK: [[B:%.*]] = add i64 192, [[A]] +; CHECK: alloca {{.*}} [[B]] + +; We expect three memcpy operations: one for the general purpose registers, +; one for floating-point/SIMD ones, and one for thre remaining arguments. + +; Propagate the GR shadow values on for the va_list::__gp_top, adjust the +; offset in the __msan_va_arg_tls based on va_list:__gp_off, and finally +; issue the memcpy. +; CHECK: [[GRP:%.*]] = getelementptr inbounds i8, ptr {{%.*}}, i64 {{%.*}} +; CHECK: [[GRSIZE:%.*]] = sub i64 64, {{%.*}} +; CHECK: call void @llvm.memcpy.p0.p0.i64(ptr align 8 {{%.*}}, ptr align 8 [[GRP]], i64 [[GRSIZE]], i1 false) + +; Propagate the VR shadow values on for the va_list::__vr_top, adjust the +; offset in the __msan_va_arg_tls based on va_list:__vr_off, and finally +; issue the memcpy. +; CHECK: [[VRP:%.*]] = getelementptr inbounds i8, ptr {{%.*}}, i64 {{%.*}} +; CHECK: [[VRSIZE:%.*]] = sub i64 128, {{%.*}} +; CHECK: call void @llvm.memcpy.p0.p0.i64(ptr align 8 {{%.*}}, ptr align 8 [[VRP]], i64 [[VRSIZE]], i1 false) + +; Copy the
[clang-tools-extra] [sanitizer][msan] fix AArch64 vararg support for KMSAN (PR #70659)
https://github.com/ramosian-glider closed https://github.com/llvm/llvm-project/pull/70659 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[compiler-rt] [llvm] [clang-tools-extra] [clang] [lldb] [libcxx] [libc] [flang] [sanitizer][msan] fix AArch64 vararg support for KMSAN (PR #70660)
https://github.com/ramosian-glider updated https://github.com/llvm/llvm-project/pull/70660 >From 3be71f474ee11326567458c8145c3b4e56031189 Mon Sep 17 00:00:00 2001 From: Alexander Potapenko Date: Mon, 30 Oct 2023 12:18:47 +0100 Subject: [PATCH 1/2] [sanitizer][msan] fix AArch64 vararg support for KMSAN Cast StackSaveAreaPtr, GrRegSaveAreaPtr, VrRegSaveAreaPtr to pointers to fix assertions in getShadowOriginPtrKernel(). Fixes: https://github.com/llvm/llvm-project/issues/69738 Patch by Mark Johnston. --- .../Instrumentation/MemorySanitizer.cpp | 10 ++-- .../MemorySanitizer/AArch64/vararg-kmsan.ll | 51 +++ .../MemorySanitizer/X86/vararg.ll | 1 + 3 files changed, 59 insertions(+), 3 deletions(-) create mode 100644 llvm/test/Instrumentation/MemorySanitizer/AArch64/vararg-kmsan.ll diff --git a/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp b/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp index e72db2d9d770eef..315d7c96ec65390 100644 --- a/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp @@ -5258,21 +5258,25 @@ struct VarArgAArch64Helper : public VarArgHelper { // we need to adjust the offset for both GR and VR fields based on // the __{gr,vr}_offs value (since they are stores based on incoming // named arguments). + Type *RegSaveAreaPtrTy = IRB.getInt8PtrTy(); // Read the stack pointer from the va_list. - Value *StackSaveAreaPtr = getVAField64(IRB, VAListTag, 0); + Value *StackSaveAreaPtr = + IRB.CreateIntToPtr(getVAField64(IRB, VAListTag, 0), RegSaveAreaPtrTy); // Read both the __gr_top and __gr_off and add them up. Value *GrTopSaveAreaPtr = getVAField64(IRB, VAListTag, 8); Value *GrOffSaveArea = getVAField32(IRB, VAListTag, 24); - Value *GrRegSaveAreaPtr = IRB.CreateAdd(GrTopSaveAreaPtr, GrOffSaveArea); + Value *GrRegSaveAreaPtr = IRB.CreateIntToPtr( + IRB.CreateAdd(GrTopSaveAreaPtr, GrOffSaveArea), RegSaveAreaPtrTy); // Read both the __vr_top and __vr_off and add them up. Value *VrTopSaveAreaPtr = getVAField64(IRB, VAListTag, 16); Value *VrOffSaveArea = getVAField32(IRB, VAListTag, 28); - Value *VrRegSaveAreaPtr = IRB.CreateAdd(VrTopSaveAreaPtr, VrOffSaveArea); + Value *VrRegSaveAreaPtr = IRB.CreateIntToPtr( + IRB.CreateAdd(VrTopSaveAreaPtr, VrOffSaveArea), RegSaveAreaPtrTy); // It does not know how many named arguments is being used and, on the // callsite all the arguments were saved. Since __gr_off is defined as diff --git a/llvm/test/Instrumentation/MemorySanitizer/AArch64/vararg-kmsan.ll b/llvm/test/Instrumentation/MemorySanitizer/AArch64/vararg-kmsan.ll new file mode 100644 index 000..2189424cd76faaf --- /dev/null +++ b/llvm/test/Instrumentation/MemorySanitizer/AArch64/vararg-kmsan.ll @@ -0,0 +1,51 @@ +; RUN: opt < %s -S -passes=msan -msan-kernel=1 2>&1 | FileCheck %s + +target datalayout = "e-m:e-i64:64-i128:128-n32:64-S128" +target triple = "aarch64-unknown-linux-gnu" + +%struct.__va_list = type { ptr, ptr, ptr, i32, i32 } + +define i32 @foo(i32 %guard, ...) { + %vl = alloca %struct.__va_list, align 8 + call void @llvm.lifetime.start.p0(i64 32, ptr %vl) + call void @llvm.va_start(ptr %vl) + call void @llvm.va_end(ptr %vl) + call void @llvm.lifetime.end.p0(i64 32, ptr %vl) + ret i32 0 +} + +; First check if the variadic shadow values are saved in stack with correct +; size (192 is total of general purpose registers size, 64, plus total of +; floating-point registers size, 128). + +; CHECK-LABEL: @foo +; CHECK: [[A:%.*]] = load {{.*}} ptr %va_arg_overflow_size +; CHECK: [[B:%.*]] = add i64 192, [[A]] +; CHECK: alloca {{.*}} [[B]] + +; We expect three memcpy operations: one for the general purpose registers, +; one for floating-point/SIMD ones, and one for thre remaining arguments. + +; Propagate the GR shadow values on for the va_list::__gp_top, adjust the +; offset in the __msan_va_arg_tls based on va_list:__gp_off, and finally +; issue the memcpy. +; CHECK: [[GRP:%.*]] = getelementptr inbounds i8, ptr {{%.*}}, i64 {{%.*}} +; CHECK: [[GRSIZE:%.*]] = sub i64 64, {{%.*}} +; CHECK: call void @llvm.memcpy.p0.p0.i64(ptr align 8 {{%.*}}, ptr align 8 [[GRP]], i64 [[GRSIZE]], i1 false) + +; Propagate the VR shadow values on for the va_list::__vr_top, adjust the +; offset in the __msan_va_arg_tls based on va_list:__vr_off, and finally +; issue the memcpy. +; CHECK: [[VRP:%.*]] = getelementptr inbounds i8, ptr {{%.*}}, i64 {{%.*}} +; CHECK: [[VRSIZE:%.*]] = sub i64 128, {{%.*}} +; CHECK: call void @llvm.memcpy.p0.p0.i64(ptr align 8 {{%.*}}, ptr align 8 [[VRP]], i64 [[VRSIZE]], i1 false) + +; Copy the remaining shadow values on the va_list::__stack position (it is +; on the constant offset of 192 from __msan_va_arg_tls). +; CHECK: [[STACK:%.*]] = getelementptr inbounds i8, ptr {{%.*}}, i32 192 +; C
[clang] dd145f9 - [asan] Add support for disable_sanitizer_instrumentation attribute
Author: Alexander Potapenko Date: 2022-02-15T14:06:12+01:00 New Revision: dd145f953db3dafbc019f1d3783bb4f09a28af92 URL: https://github.com/llvm/llvm-project/commit/dd145f953db3dafbc019f1d3783bb4f09a28af92 DIFF: https://github.com/llvm/llvm-project/commit/dd145f953db3dafbc019f1d3783bb4f09a28af92.diff LOG: [asan] Add support for disable_sanitizer_instrumentation attribute For ASan this will effectively serve as a synonym for __attribute__((no_sanitize("address"))) This is a reland of https://reviews.llvm.org/D114421 Reviewed By: melver, eugenis Differential Revision: https://reviews.llvm.org/D119726 Added: llvm/test/Instrumentation/AddressSanitizer/asan-disable-sanitizer-instrumentation.ll Modified: clang/docs/AddressSanitizer.rst clang/lib/CodeGen/CodeGenFunction.cpp clang/lib/CodeGen/SanitizerMetadata.cpp clang/test/CodeGen/address-safety-attr-flavors.cpp clang/test/CodeGen/asan-globals.cpp llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp Removed: diff --git a/clang/docs/AddressSanitizer.rst b/clang/docs/AddressSanitizer.rst index 06b53e2e5da0b..fe5f683580a46 100644 --- a/clang/docs/AddressSanitizer.rst +++ b/clang/docs/AddressSanitizer.rst @@ -229,6 +229,12 @@ compilers, so we suggest to use it together with The same attribute used on a global variable prevents AddressSanitizer from adding redzones around it and detecting out of bounds accesses. + +AddressSanitizer also supports +``__attribute__((disable_sanitizer_instrumentation))``. This attribute +works similar to ``__attribute__((no_sanitize("address")))``, but it also +prevents instrumentation performed by other sanitizers. + Suppressing Errors in Recompiled Code (Ignorelist) -- diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp index ba077650f237a..bd29842afbaa9 100644 --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -383,9 +383,6 @@ void CodeGenFunction::FinishFunction(SourceLocation EndLoc) { "__cyg_profile_func_exit"); } - if (ShouldSkipSanitizerInstrumentation()) -CurFn->addFnAttr(llvm::Attribute::DisableSanitizerInstrumentation); - // Emit debug descriptor for function end. if (CGDebugInfo *DI = getDebugInfo()) DI->EmitFunctionEnd(Builder, CurFn); @@ -767,17 +764,22 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy, Fn->addFnAttr(llvm::Attribute::NoSanitizeCoverage); } - // Apply sanitizer attributes to the function. - if (SanOpts.hasOneOf(SanitizerKind::Address | SanitizerKind::KernelAddress)) -Fn->addFnAttr(llvm::Attribute::SanitizeAddress); - if (SanOpts.hasOneOf(SanitizerKind::HWAddress | SanitizerKind::KernelHWAddress)) -Fn->addFnAttr(llvm::Attribute::SanitizeHWAddress); - if (SanOpts.has(SanitizerKind::MemTag)) -Fn->addFnAttr(llvm::Attribute::SanitizeMemTag); - if (SanOpts.has(SanitizerKind::Thread)) -Fn->addFnAttr(llvm::Attribute::SanitizeThread); - if (SanOpts.hasOneOf(SanitizerKind::Memory | SanitizerKind::KernelMemory)) -Fn->addFnAttr(llvm::Attribute::SanitizeMemory); + if (ShouldSkipSanitizerInstrumentation()) { +CurFn->addFnAttr(llvm::Attribute::DisableSanitizerInstrumentation); + } else { +// Apply sanitizer attributes to the function. +if (SanOpts.hasOneOf(SanitizerKind::Address | SanitizerKind::KernelAddress)) + Fn->addFnAttr(llvm::Attribute::SanitizeAddress); +if (SanOpts.hasOneOf(SanitizerKind::HWAddress | + SanitizerKind::KernelHWAddress)) + Fn->addFnAttr(llvm::Attribute::SanitizeHWAddress); +if (SanOpts.has(SanitizerKind::MemTag)) + Fn->addFnAttr(llvm::Attribute::SanitizeMemTag); +if (SanOpts.has(SanitizerKind::Thread)) + Fn->addFnAttr(llvm::Attribute::SanitizeThread); +if (SanOpts.hasOneOf(SanitizerKind::Memory | SanitizerKind::KernelMemory)) + Fn->addFnAttr(llvm::Attribute::SanitizeMemory); + } if (SanOpts.has(SanitizerKind::SafeStack)) Fn->addFnAttr(llvm::Attribute::SafeStack); if (SanOpts.has(SanitizerKind::ShadowCallStack)) diff --git a/clang/lib/CodeGen/SanitizerMetadata.cpp b/clang/lib/CodeGen/SanitizerMetadata.cpp index 009965a36c396..9e26d242d3a7e 100644 --- a/clang/lib/CodeGen/SanitizerMetadata.cpp +++ b/clang/lib/CodeGen/SanitizerMetadata.cpp @@ -73,6 +73,8 @@ void SanitizerMetadata::reportGlobalToASan(llvm::GlobalVariable *GV, for (auto Attr : D.specific_attrs()) if (Attr->getMask() & SanitizerKind::Address) IsExcluded = true; + if (D.hasAttr()) +IsExcluded = true; reportGlobalToASan(GV, D.getLocation(), OS.str(), D.getType(), IsDynInit, IsExcluded); } diff --git a/clang/test/CodeGen/address-safety-attr-flavors.cpp b/clang/test/CodeGen/address-safety-attr-flavors.cpp index e6d17ed2da340..ef81
[clang] 05ee1f4 - Revert "[asan] Add support for disable_sanitizer_instrumentation attribute"
Author: Alexander Potapenko Date: 2022-02-15T15:04:53+01:00 New Revision: 05ee1f4af8972f021917fb1f96624050fc6268bd URL: https://github.com/llvm/llvm-project/commit/05ee1f4af8972f021917fb1f96624050fc6268bd DIFF: https://github.com/llvm/llvm-project/commit/05ee1f4af8972f021917fb1f96624050fc6268bd.diff LOG: Revert "[asan] Add support for disable_sanitizer_instrumentation attribute" This reverts commit dd145f953db3dafbc019f1d3783bb4f09a28af92. https://reviews.llvm.org/D119726, like https://reviews.llvm.org/D114421, still causes TSan to fail, see https://lab.llvm.org/buildbot/#/builders/70/builds/18020 Differential Revision: https://reviews.llvm.org/D119838 Added: Modified: clang/docs/AddressSanitizer.rst clang/lib/CodeGen/CodeGenFunction.cpp clang/lib/CodeGen/SanitizerMetadata.cpp clang/test/CodeGen/address-safety-attr-flavors.cpp clang/test/CodeGen/asan-globals.cpp llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp Removed: llvm/test/Instrumentation/AddressSanitizer/asan-disable-sanitizer-instrumentation.ll diff --git a/clang/docs/AddressSanitizer.rst b/clang/docs/AddressSanitizer.rst index fe5f683580a46..06b53e2e5da0b 100644 --- a/clang/docs/AddressSanitizer.rst +++ b/clang/docs/AddressSanitizer.rst @@ -229,12 +229,6 @@ compilers, so we suggest to use it together with The same attribute used on a global variable prevents AddressSanitizer from adding redzones around it and detecting out of bounds accesses. - -AddressSanitizer also supports -``__attribute__((disable_sanitizer_instrumentation))``. This attribute -works similar to ``__attribute__((no_sanitize("address")))``, but it also -prevents instrumentation performed by other sanitizers. - Suppressing Errors in Recompiled Code (Ignorelist) -- diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp index bd29842afbaa9..a7f62b4a4e30a 100644 --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -383,6 +383,9 @@ void CodeGenFunction::FinishFunction(SourceLocation EndLoc) { "__cyg_profile_func_exit"); } + if (ShouldSkipSanitizerInstrumentation()) +CurFn->addFnAttr(llvm::Attribute::DisableSanitizerInstrumentation); + // Emit debug descriptor for function end. if (CGDebugInfo *DI = getDebugInfo()) DI->EmitFunctionEnd(Builder, CurFn); @@ -764,22 +767,18 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy, Fn->addFnAttr(llvm::Attribute::NoSanitizeCoverage); } - if (ShouldSkipSanitizerInstrumentation()) { -CurFn->addFnAttr(llvm::Attribute::DisableSanitizerInstrumentation); - } else { -// Apply sanitizer attributes to the function. -if (SanOpts.hasOneOf(SanitizerKind::Address | SanitizerKind::KernelAddress)) - Fn->addFnAttr(llvm::Attribute::SanitizeAddress); -if (SanOpts.hasOneOf(SanitizerKind::HWAddress | - SanitizerKind::KernelHWAddress)) - Fn->addFnAttr(llvm::Attribute::SanitizeHWAddress); -if (SanOpts.has(SanitizerKind::MemTag)) - Fn->addFnAttr(llvm::Attribute::SanitizeMemTag); -if (SanOpts.has(SanitizerKind::Thread)) - Fn->addFnAttr(llvm::Attribute::SanitizeThread); -if (SanOpts.hasOneOf(SanitizerKind::Memory | SanitizerKind::KernelMemory)) - Fn->addFnAttr(llvm::Attribute::SanitizeMemory); - } + // Apply sanitizer attributes to the function. + if (SanOpts.hasOneOf(SanitizerKind::Address | SanitizerKind::KernelAddress)) +Fn->addFnAttr(llvm::Attribute::SanitizeAddress); + if (SanOpts.hasOneOf(SanitizerKind::HWAddress | + SanitizerKind::KernelHWAddress)) +Fn->addFnAttr(llvm::Attribute::SanitizeHWAddress); + if (SanOpts.has(SanitizerKind::MemTag)) +Fn->addFnAttr(llvm::Attribute::SanitizeMemTag); + if (SanOpts.has(SanitizerKind::Thread)) +Fn->addFnAttr(llvm::Attribute::SanitizeThread); + if (SanOpts.hasOneOf(SanitizerKind::Memory | SanitizerKind::KernelMemory)) +Fn->addFnAttr(llvm::Attribute::SanitizeMemory); if (SanOpts.has(SanitizerKind::SafeStack)) Fn->addFnAttr(llvm::Attribute::SafeStack); if (SanOpts.has(SanitizerKind::ShadowCallStack)) diff --git a/clang/lib/CodeGen/SanitizerMetadata.cpp b/clang/lib/CodeGen/SanitizerMetadata.cpp index 9e26d242d3a7e..009965a36c396 100644 --- a/clang/lib/CodeGen/SanitizerMetadata.cpp +++ b/clang/lib/CodeGen/SanitizerMetadata.cpp @@ -73,8 +73,6 @@ void SanitizerMetadata::reportGlobalToASan(llvm::GlobalVariable *GV, for (auto Attr : D.specific_attrs()) if (Attr->getMask() & SanitizerKind::Address) IsExcluded = true; - if (D.hasAttr()) -IsExcluded = true; reportGlobalToASan(GV, D.getLocation(), OS.str(), D.getType(), IsDynInit, IsExcluded); } diff --git a/clang/test/CodeGen/address-safety-attr-flavors.cpp
[libcxxabi] [libcxx] [libc] [lld] [flang] [llvm] [clang] [lldb] [msan] Unpoison indirect outputs for userspace using memset for large operands (PR #79924)
@@ -4552,16 +4552,22 @@ struct MemorySanitizerVisitor : public InstVisitor { } if (!ElemTy->isSized()) return; -Value *SizeVal = - IRB.CreateTypeSize(MS.IntptrTy, DL.getTypeStoreSize(ElemTy)); +auto Size = DL.getTypeStoreSize(ElemTy); +Value *SizeVal = IRB.CreateTypeSize(MS.IntptrTy, Size); if (MS.CompileKernel) { IRB.CreateCall(MS.MsanInstrumentAsmStoreFn, {Operand, SizeVal}); } else { // ElemTy, derived from elementtype(), does not encode the alignment of // the pointer. Conservatively assume that the shadow memory is unaligned. + // When Size is large, avoid StoreInst as it would expand to many + // instructions. auto [ShadowPtr, _] = getShadowOriginPtrUserspace(Operand, IRB, IRB.getInt8Ty(), Align(1)); - IRB.CreateAlignedStore(getCleanShadow(ElemTy), ShadowPtr, Align(1)); + if (Size <= 32) ramosian-glider wrote: Maybe some comment wouldn't hurt here to clarify this constant. https://github.com/llvm/llvm-project/pull/79924 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r370335 - [CodeGen]: don't treat structures returned in registers as memory inputs
Author: glider Date: Thu Aug 29 04:21:41 2019 New Revision: 370335 URL: http://llvm.org/viewvc/llvm-project?rev=370335&view=rev Log: [CodeGen]: don't treat structures returned in registers as memory inputs Summary: The "=r" output constraint for a structure variable passed to inline asm shouldn't be converted to "=*r", as this changes the asm directive semantics and prevents DSE optimizations. Instead, preserve the constraints and return such structures as integers of corresponding size, which are converted back to structures when storing the result. Fixes PR42672. Subscribers: cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D65234 Added: cfe/trunk/test/CodeGen/x86_64-PR42672.c Modified: cfe/trunk/lib/CodeGen/CGStmt.cpp cfe/trunk/test/CodeGen/asm-attrs.c Modified: cfe/trunk/lib/CodeGen/CGStmt.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGStmt.cpp?rev=370335&r1=370334&r2=370335&view=diff == --- cfe/trunk/lib/CodeGen/CGStmt.cpp (original) +++ cfe/trunk/lib/CodeGen/CGStmt.cpp Thu Aug 29 04:21:41 2019 @@ -1984,6 +1984,7 @@ void CodeGenFunction::EmitAsmStmt(const std::vector ResultTruncRegTypes; std::vector ArgTypes; std::vector Args; + llvm::BitVector ResultTypeRequiresCast; // Keep track of inout constraints. std::string InOutConstraints; @@ -2022,13 +2023,23 @@ void CodeGenFunction::EmitAsmStmt(const // If this is a register output, then make the inline asm return it // by-value. If this is a memory result, return the value by-reference. -if (!Info.allowsMemory() && hasScalarEvaluationKind(OutExpr->getType())) { +bool isScalarizableAggregate = +hasAggregateEvaluationKind(OutExpr->getType()); +if (!Info.allowsMemory() && (hasScalarEvaluationKind(OutExpr->getType()) || + isScalarizableAggregate)) { Constraints += "=" + OutputConstraint; ResultRegQualTys.push_back(OutExpr->getType()); ResultRegDests.push_back(Dest); - ResultRegTypes.push_back(ConvertTypeForMem(OutExpr->getType())); - ResultTruncRegTypes.push_back(ResultRegTypes.back()); - + ResultTruncRegTypes.push_back(ConvertTypeForMem(OutExpr->getType())); + if (Info.allowsRegister() && isScalarizableAggregate) { +ResultTypeRequiresCast.push_back(true); +unsigned Size = getContext().getTypeSize(OutExpr->getType()); +llvm::Type *ConvTy = llvm::IntegerType::get(getLLVMContext(), Size); +ResultRegTypes.push_back(ConvTy); + } else { +ResultTypeRequiresCast.push_back(false); +ResultRegTypes.push_back(ResultTruncRegTypes.back()); + } // If this output is tied to an input, and if the input is larger, then // we need to set the actual result type of the inline asm node to be the // same as the input type. @@ -2271,6 +2282,9 @@ void CodeGenFunction::EmitAsmStmt(const assert(RegResults.size() == ResultRegTypes.size()); assert(RegResults.size() == ResultTruncRegTypes.size()); assert(RegResults.size() == ResultRegDests.size()); + // ResultRegDests can be also populated by addReturnRegisterOutputs() above, + // in which case its size may grow. + assert(ResultTypeRequiresCast.size() <= ResultRegDests.size()); for (unsigned i = 0, e = RegResults.size(); i != e; ++i) { llvm::Value *Tmp = RegResults[i]; @@ -2300,7 +2314,24 @@ void CodeGenFunction::EmitAsmStmt(const } } -EmitStoreThroughLValue(RValue::get(Tmp), ResultRegDests[i]); +LValue Dest = ResultRegDests[i]; +// ResultTypeRequiresCast elements correspond to the first +// ResultTypeRequiresCast.size() elements of RegResults. +if ((i < ResultTypeRequiresCast.size()) && ResultTypeRequiresCast[i]) { + unsigned Size = getContext().getTypeSize(ResultRegQualTys[i]); + Address A = Builder.CreateBitCast(Dest.getAddress(), +ResultRegTypes[i]->getPointerTo()); + QualType Ty = getContext().getIntTypeForBitwidth(Size, /*Signed*/ false); + if (Ty.isNull()) { +const Expr *OutExpr = S.getOutputExpr(i); +CGM.Error( +OutExpr->getExprLoc(), +"impossible constraint in asm: can't store struct into a register"); +return; + } + Dest = MakeAddrLValue(A, Ty); +} +EmitStoreThroughLValue(RValue::get(Tmp), Dest); } } Modified: cfe/trunk/test/CodeGen/asm-attrs.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/asm-attrs.c?rev=370335&r1=370334&r2=370335&view=diff == --- cfe/trunk/test/CodeGen/asm-attrs.c (original) +++ cfe/trunk/test/CodeGen/asm-attrs.c Thu Aug 29 04:21:41 2019 @@ -8,7 +8,7 @@ // CHECK: call i32 asm "foo5", {{.*}} [[READONLY]] // CHECK: call i32 asm "foo6", {{.*}} [[NOATTRS]] // CHECK: call void asm sideeffect "
r370444 - [CodeGen]: fix error message for "=r" asm constraint
Author: glider Date: Fri Aug 30 01:58:46 2019 New Revision: 370444 URL: http://llvm.org/viewvc/llvm-project?rev=370444&view=rev Log: [CodeGen]: fix error message for "=r" asm constraint Summary: Nico Weber reported that the following code: char buf[9]; asm("" : "=r" (buf)); yields the "impossible constraint in asm: can't store struct into a register" error message, although |buf| is not a struct (see http://crbug.com/999160). Make the error message more generic and add a test for it. Also make sure other tests in x86_64-PR42672.c check for the full error message. Reviewers: eli.friedman, thakis Subscribers: cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D66948 Modified: cfe/trunk/lib/CodeGen/CGStmt.cpp cfe/trunk/test/CodeGen/x86_64-PR42672.c Modified: cfe/trunk/lib/CodeGen/CGStmt.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGStmt.cpp?rev=370444&r1=370443&r2=370444&view=diff == --- cfe/trunk/lib/CodeGen/CGStmt.cpp (original) +++ cfe/trunk/lib/CodeGen/CGStmt.cpp Fri Aug 30 01:58:46 2019 @@ -2326,7 +2326,7 @@ void CodeGenFunction::EmitAsmStmt(const const Expr *OutExpr = S.getOutputExpr(i); CGM.Error( OutExpr->getExprLoc(), -"impossible constraint in asm: can't store struct into a register"); +"impossible constraint in asm: can't store value into a register"); return; } Dest = MakeAddrLValue(A, Ty); Modified: cfe/trunk/test/CodeGen/x86_64-PR42672.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/x86_64-PR42672.c?rev=370444&r1=370443&r2=370444&view=diff == --- cfe/trunk/test/CodeGen/x86_64-PR42672.c (original) +++ cfe/trunk/test/CodeGen/x86_64-PR42672.c Fri Aug 30 01:58:46 2019 @@ -4,6 +4,7 @@ // RUN: not %clang_cc1 -triple=x86_64-unknown-linux-gnu -DIMPOSSIBLE_BIG -emit-llvm %s -o - 2>&1 | FileCheck %s --check-prefix=CHECK-IMPOSSIBLE_BIG // RUN: %clang_cc1 -triple=x86_64-unknown-linux-gnu -DPOSSIBLE_X -emit-llvm %s -o - 2>&1 | FileCheck %s --check-prefix=CHECK-X // RUN: not %clang_cc1 -triple=x86_64-unknown-linux-gnu -DIMPOSSIBLE_X -emit-llvm %s -o - 2>&1 | FileCheck %s --check-prefix=CHECK-IMPOSSIBLE_X +// RUN: not %clang_cc1 -triple=x86_64-unknown-linux-gnu -DIMPOSSIBLE_9BYTES -emit-llvm %s -o - 2>&1 | FileCheck %s --check-prefix=CHECK-IMPOSSIBLE_9BYTES // Make sure Clang doesn't treat |lockval| as asm input. void _raw_spin_lock(void) { @@ -57,7 +58,7 @@ void odd_struct(void) { : "=r"(str)); #endif } -// CHECK-IMPOSSIBLE_ODD: impossible constraint in asm +// CHECK-IMPOSSIBLE_ODD: impossible constraint in asm: can't store value into a register // Check Clang reports an error if attempting to return a big structure via a register. void big_struct(void) { @@ -69,7 +70,7 @@ void big_struct(void) { : "=r"(str)); #endif } -// CHECK-IMPOSSIBLE_BIG: impossible constraint in asm +// CHECK-IMPOSSIBLE_BIG: impossible constraint in asm: can't store value into a register // Clang is able to emit LLVM IR for an 16-byte structure. void x_constraint_fit() { @@ -100,3 +101,17 @@ void x_constraint_nofit() { } // CHECK-IMPOSSIBLE_X: invalid output size for constraint + +// http://crbug.com/999160 +// Clang used to report the following message: +// "impossible constraint in asm: can't store struct into a register" +// for the assembly directive below, although there's no struct. +void crbug_999160_regtest() { +#ifdef IMPOSSIBLE_9BYTES + char buf[9]; + asm("" + : "=r"(buf)); +#endif +} + +// CHECK-IMPOSSIBLE_9BYTES: impossible constraint in asm: can't store value into a register ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r310600 - [sanitizer-coverage] Change cmp instrumentation to distinguish const operands
Author: glider Date: Thu Aug 10 08:00:13 2017 New Revision: 310600 URL: http://llvm.org/viewvc/llvm-project?rev=310600&view=rev Log: [sanitizer-coverage] Change cmp instrumentation to distinguish const operands This implementation of SanitizerCoverage instrumentation inserts different callbacks depending on constantness of operands: 1. If both operands are non-const, then a usual __sanitizer_cov_trace_cmp[1248] call is inserted. 2. If exactly one operand is const, then a __sanitizer_cov_trace_const_cmp[1248] call is inserted. The first argument of the call is always the constant one. 3. If both operands are const, then no callback is inserted. This separation comes useful in fuzzing when tasks like "find one operand of the comparison in input arguments and replace it with the other one" have to be done. The new instrumentation allows us to not waste time on searching the constant operands in the input. Patch by Victor Chibotaru. Modified: cfe/trunk/docs/SanitizerCoverage.rst Modified: cfe/trunk/docs/SanitizerCoverage.rst URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/SanitizerCoverage.rst?rev=310600&r1=310599&r2=310600&view=diff == --- cfe/trunk/docs/SanitizerCoverage.rst (original) +++ cfe/trunk/docs/SanitizerCoverage.rst Thu Aug 10 08:00:13 2017 @@ -211,6 +211,14 @@ the `LLVM GEP instructions
[clang] 7ab44b5 - [msan] Allow KMSAN to use -fsanitize-memory-param-retval
Author: Alexander Potapenko Date: 2022-06-17T10:54:20+02:00 New Revision: 7ab44b5c2155245d115ba8642fcaabe65b54e44b URL: https://github.com/llvm/llvm-project/commit/7ab44b5c2155245d115ba8642fcaabe65b54e44b DIFF: https://github.com/llvm/llvm-project/commit/7ab44b5c2155245d115ba8642fcaabe65b54e44b.diff LOG: [msan] Allow KMSAN to use -fsanitize-memory-param-retval Let -fsanitize-memory-param-retval be used together with -fsanitize=kernel-memory, so that it can be applied when building the Linux kernel. Also add clang/test/CodeGen/kmsan-param-retval.c to ensure that -fsanitize-memory-param-retval eliminates shadow accesses for parameters marked as undef. Reviewed By: eugenis, vitalybuka Differential Revision: https://reviews.llvm.org/D127860 Added: clang/test/CodeGen/kmsan-param-retval.c Modified: clang/lib/Driver/SanitizerArgs.cpp clang/test/Driver/fsanitize-memory-param-retval.c Removed: diff --git a/clang/lib/Driver/SanitizerArgs.cpp b/clang/lib/Driver/SanitizerArgs.cpp index edb1bfbe9bdf..55d44691050b 100644 --- a/clang/lib/Driver/SanitizerArgs.cpp +++ b/clang/lib/Driver/SanitizerArgs.cpp @@ -648,6 +648,11 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC, options::OPT_fno_sanitize_memory_param_retval, MsanParamRetval); NeedPIE |= !(TC.getTriple().isOSLinux() && TC.getTriple().getArch() == llvm::Triple::x86_64); + } else if (AllAddedKinds & SanitizerKind::KernelMemory) { +MsanUseAfterDtor = false; +MsanParamRetval = Args.hasFlag( +options::OPT_fsanitize_memory_param_retval, +options::OPT_fno_sanitize_memory_param_retval, MsanParamRetval); } else { MsanUseAfterDtor = false; MsanParamRetval = false; diff --git a/clang/test/CodeGen/kmsan-param-retval.c b/clang/test/CodeGen/kmsan-param-retval.c new file mode 100644 index ..3d952c01c7f7 --- /dev/null +++ b/clang/test/CodeGen/kmsan-param-retval.c @@ -0,0 +1,36 @@ +// RUN: %clang_cc1 -triple x86_64-linux-gnu -S -emit-llvm -O2 -fsanitize=kernel-memory -no-enable-noundef-analysis -o - %s | \ +// RUN: FileCheck %s --check-prefix=CLEAN +// RUN: %clang_cc1 -triple x86_64-linux-gnu -S -emit-llvm -O2 -fsanitize=kernel-memory -o - %s | \ +// RUN: FileCheck %s --check-prefixes=NOUNDEF,NOUNDEF_ONLY +// RUN: %clang_cc1 -triple x86_64-linux-gnu -S -emit-llvm -O2 -fsanitize=kernel-memory -mllvm -msan-eager-checks -o - %s | \ +// RUN: FileCheck %s --check-prefixes=NOUNDEF,EAGER +// RUN: %clang_cc1 -triple x86_64-linux-gnu -S -emit-llvm -O2 -fsanitize=kernel-memory -no-enable-noundef-analysis -fsanitize-memory-param-retval -o - %s | \ +// RUN: FileCheck %s --check-prefixes=CLEAN +// RUN: %clang_cc1 -triple x86_64-linux-gnu -S -emit-llvm -O2 -fsanitize=kernel-memory -fsanitize-memory-param-retval -o - %s | \ +// RUN: FileCheck %s --check-prefixes=NOUNDEF,EAGER + +void foo(); + +void bar(int x) { + if (x) +foo(); +} + + +// CLEAN: define dso_local void @bar(i32 %x) +// NOUNDEF: define dso_local void @bar(i32 noundef %x) +// +// %param_shadow assignment gets optimized away with -O2, because it is at the beginning of the +// struct returned by __msan_get_context_state(). Use %param_origin as a sign that the shadow of +// the first argument is being used. +// +// Without noundef analysis, KMSAN emits metadata checks for the function parameter. +// CLEAN:load i32, ptr %param_origin +// +// With noundef analysis enabled, but without eager checks, KMSAN still emits metadata checks, +// although the parameter is known to be defined. +// NOUNDEF_ONLY: load i32, ptr %param_origin +// +// With noundef analysis and eager checks enabled, KMSAN won't emit metadata checks for function +// parameters. +// EAGER-NOT:load i32, ptr %param_origin diff --git a/clang/test/Driver/fsanitize-memory-param-retval.c b/clang/test/Driver/fsanitize-memory-param-retval.c index 98ca16e02777..d82d20812186 100644 --- a/clang/test/Driver/fsanitize-memory-param-retval.c +++ b/clang/test/Driver/fsanitize-memory-param-retval.c @@ -3,6 +3,8 @@ // RUN: %clang -target aarch64-linux-gnu %s -fsanitize=memory -fsanitize-memory-param-retval -c -### 2>&1 | FileCheck %s // RUN: %clang -target riscv32-linux-gnu %s -fsanitize=memory -fsanitize-memory-param-retval -c -### 2>&1 | FileCheck %s // RUN: %clang -target riscv64-linux-gnu %s -fsanitize=memory -fsanitize-memory-param-retval -c -### 2>&1 | FileCheck %s +// RUN: %clang -target x86_64-linux-gnu %s -fsanitize=kernel-memory -fsanitize-memory-param-retval -c -### 2>&1 | FileCheck %s + // CHECK: "-fsanitize-memory-param-retval" // RUN: %clang -target aarch64-linux-gnu -fsyntax-only %s -fsanitize=memory -fsanitize-memory-param-retval -c -### 2>&1 | FileCheck --check-prefix=11 %s ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-
Re: r270009 - Make Sema::getPrintingPolicy less ridiculously expensive. This used to perform
Pretty impressive, thank you! I'm gonna give it a shot later today. sent from phone On May 19, 2016 3:45 AM, "Richard Smith via cfe-commits" < cfe-commits@lists.llvm.org> wrote: > Author: rsmith > Date: Wed May 18 20:39:10 2016 > New Revision: 270009 > > URL: http://llvm.org/viewvc/llvm-project?rev=270009&view=rev > Log: > Make Sema::getPrintingPolicy less ridiculously expensive. This used to > perform > an identifier table lookup, *and* copy the LangOptions (including various > std::vectors). Twice. We call this function once each time we > start > parsing a declaration specifier sequence, and once for each call to > Sema::Diag. > > This reduces the compile time for a sample .c file from the linux kernel > by 20%. > > Modified: > cfe/trunk/include/clang/AST/ASTContext.h > cfe/trunk/include/clang/AST/PrettyPrinter.h > cfe/trunk/lib/AST/DeclarationName.cpp > cfe/trunk/lib/AST/StmtPrinter.cpp > cfe/trunk/lib/AST/TypePrinter.cpp > cfe/trunk/lib/Parse/ParseDecl.cpp > cfe/trunk/lib/Sema/Sema.cpp > cfe/trunk/lib/Sema/SemaCodeComplete.cpp > cfe/trunk/test/Analysis/initializers-cfg-output.cpp > cfe/trunk/test/Analysis/temp-obj-dtors-cfg-output.cpp > cfe/trunk/test/SemaCXX/member-pointer.cpp > > Modified: cfe/trunk/include/clang/AST/ASTContext.h > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=270009&r1=270008&r2=270009&view=diff > > == > --- cfe/trunk/include/clang/AST/ASTContext.h (original) > +++ cfe/trunk/include/clang/AST/ASTContext.h Wed May 18 20:39:10 2016 > @@ -243,6 +243,9 @@ class ASTContext : public RefCountedBase >QualType ObjCClassRedefinitionType; >QualType ObjCSelRedefinitionType; > > + /// The identifier 'bool'. > + mutable IdentifierInfo *BoolName = nullptr; > + >/// The identifier 'NSObject'. >IdentifierInfo *NSObjectName = nullptr; > > @@ -1457,6 +1460,13 @@ public: > return NSCopyingName; >} > > + /// Retrieve the identifier 'bool'. > + IdentifierInfo *getBoolName() const { > +if (!BoolName) > + BoolName = &Idents.get("bool"); > +return BoolName; > + } > + >IdentifierInfo *getMakeIntegerSeqName() const { > if (!MakeIntegerSeqName) >MakeIntegerSeqName = &Idents.get("__make_integer_seq"); > > Modified: cfe/trunk/include/clang/AST/PrettyPrinter.h > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/PrettyPrinter.h?rev=270009&r1=270008&r2=270009&view=diff > > == > --- cfe/trunk/include/clang/AST/PrettyPrinter.h (original) > +++ cfe/trunk/include/clang/AST/PrettyPrinter.h Wed May 18 20:39:10 2016 > @@ -32,22 +32,35 @@ public: > > /// \brief Describes how types, statements, expressions, and > /// declarations should be printed. > +/// > +/// This type is intended to be small and suitable for passing by value. > +/// It is very frequently copied. > struct PrintingPolicy { > - /// \brief Create a default printing policy for C. > + /// \brief Create a default printing policy for the specified language. >PrintingPolicy(const LangOptions &LO) > -: LangOpts(LO), Indentation(2), SuppressSpecifiers(false), > - SuppressTagKeyword(false), > +: Indentation(2), SuppressSpecifiers(false), > + SuppressTagKeyword(LO.CPlusPlus), >IncludeTagDefinition(false), SuppressScope(false), >SuppressUnwrittenScope(false), SuppressInitializers(false), >ConstantArraySizeAsWritten(false), AnonymousTagLocations(true), >SuppressStrongLifetime(false), SuppressLifetimeQualifiers(false), >SuppressTemplateArgsInCXXConstructors(false), > - Bool(LO.Bool), TerseOutput(false), PolishForDeclaration(false), > + Bool(LO.Bool), Restrict(LO.C99), > + Alignof(LO.CPlusPlus11), UnderscoreAlignof(LO.C11), > + UseVoidForZeroParams(!LO.CPlusPlus), > + TerseOutput(false), PolishForDeclaration(false), >Half(LO.Half), MSWChar(LO.MicrosoftExt && !LO.WChar), >IncludeNewlines(true), MSVCFormatting(false) { } > > - /// \brief What language we're printing. > - LangOptions LangOpts; > + /// \brief Adjust this printing policy for cases where it's known that > + /// we're printing C++ code (for instance, if AST dumping reaches a > + /// C++-only construct). This should not be used if a real LangOptions > + /// object is available. > + void adjustForCPlusPlus() { > +SuppressTagKeyword = true; > +Bool = true; > +UseVoidForZeroParams = false; > + } > >/// \brief The number of spaces to use to indent each line. >unsigned Indentation : 8; > @@ -143,10 +156,23 @@ struct PrintingPolicy { >/// constructors. >unsigned SuppressTemplateArgsInCXXConstructors : 1; > > - /// \brief Whether we can use 'bool' rather than '_Bool', even if the > language > - /// doesn't actually have 'bool' (because, e.g., it is defined as
[clang] [clang] Skip auto-init on scalar vars that have a non-constant Init and no self-ref (PR #94642)
ramosian-glider wrote: Drive-by comment: can you please either merge the two commits together, or change their descriptions so that they are not 100% identical? https://github.com/llvm/llvm-project/pull/94642 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Skip auto-init on scalar vars that have a non-constant Init and no self-ref (PR #94642)
@@ -15,7 +15,7 @@ struct Foo { int foo(unsigned n) { bool var_size_1; - long var_size_8 = 123; ramosian-glider wrote: Can we have both the test cases in which scalar variables are auto-inited and where the initialization is skipped? Something along the lines of: ``` long var_size_8_init = 123; long var_size_8_noinit; long var_size_8_init_later; ... var_size_8_init_later = 456; ``` https://github.com/llvm/llvm-project/pull/94642 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Skip auto-init on scalar vars that have a non-constant Init and no self-ref (PR #94642)
@@ -15,7 +15,7 @@ struct Foo { int foo(unsigned n) { bool var_size_1; - long var_size_8 = 123; ramosian-glider wrote: LGTM https://github.com/llvm/llvm-project/pull/94642 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] c85a264 - [asan] Add support for disable_sanitizer_instrumentation attribute
Author: Alexander Potapenko Date: 2022-02-18T09:51:54+01:00 New Revision: c85a26454d4b3dab383555c3864568b7aff9c225 URL: https://github.com/llvm/llvm-project/commit/c85a26454d4b3dab383555c3864568b7aff9c225 DIFF: https://github.com/llvm/llvm-project/commit/c85a26454d4b3dab383555c3864568b7aff9c225.diff LOG: [asan] Add support for disable_sanitizer_instrumentation attribute For ASan this will effectively serve as a synonym for __attribute__((no_sanitize("address"))). Adding the disable_sanitizer_instrumentation to functions will drop the sanitize_XXX attributes on the IR level. This is the third reland of https://reviews.llvm.org/D114421. Now that TSan test is fixed (https://reviews.llvm.org/D120050) there should be no deadlocks. Differential Revision: https://reviews.llvm.org/D120055 Added: llvm/test/Instrumentation/AddressSanitizer/asan-disable-sanitizer-instrumentation.ll Modified: clang/docs/AddressSanitizer.rst clang/lib/CodeGen/CodeGenFunction.cpp clang/lib/CodeGen/SanitizerMetadata.cpp clang/test/CodeGen/address-safety-attr-flavors.cpp clang/test/CodeGen/asan-globals.cpp llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp Removed: diff --git a/clang/docs/AddressSanitizer.rst b/clang/docs/AddressSanitizer.rst index 06b53e2e5da0b..fe5f683580a46 100644 --- a/clang/docs/AddressSanitizer.rst +++ b/clang/docs/AddressSanitizer.rst @@ -229,6 +229,12 @@ compilers, so we suggest to use it together with The same attribute used on a global variable prevents AddressSanitizer from adding redzones around it and detecting out of bounds accesses. + +AddressSanitizer also supports +``__attribute__((disable_sanitizer_instrumentation))``. This attribute +works similar to ``__attribute__((no_sanitize("address")))``, but it also +prevents instrumentation performed by other sanitizers. + Suppressing Errors in Recompiled Code (Ignorelist) -- diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp index 95091edd9ecb7..c4ccc8e1b0424 100644 --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -383,9 +383,6 @@ void CodeGenFunction::FinishFunction(SourceLocation EndLoc) { "__cyg_profile_func_exit"); } - if (ShouldSkipSanitizerInstrumentation()) -CurFn->addFnAttr(llvm::Attribute::DisableSanitizerInstrumentation); - // Emit debug descriptor for function end. if (CGDebugInfo *DI = getDebugInfo()) DI->EmitFunctionEnd(Builder, CurFn); @@ -767,18 +764,22 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy, Fn->addFnAttr(llvm::Attribute::NoSanitizeCoverage); } - // Apply sanitizer attributes to the function. - if (SanOpts.hasOneOf(SanitizerKind::Address | SanitizerKind::KernelAddress)) -Fn->addFnAttr(llvm::Attribute::SanitizeAddress); - if (SanOpts.hasOneOf(SanitizerKind::HWAddress | - SanitizerKind::KernelHWAddress)) -Fn->addFnAttr(llvm::Attribute::SanitizeHWAddress); - if (SanOpts.has(SanitizerKind::MemTag)) -Fn->addFnAttr(llvm::Attribute::SanitizeMemTag); - if (SanOpts.has(SanitizerKind::Thread)) -Fn->addFnAttr(llvm::Attribute::SanitizeThread); - if (SanOpts.hasOneOf(SanitizerKind::Memory | SanitizerKind::KernelMemory)) -Fn->addFnAttr(llvm::Attribute::SanitizeMemory); + if (ShouldSkipSanitizerInstrumentation()) { +CurFn->addFnAttr(llvm::Attribute::DisableSanitizerInstrumentation); + } else { +// Apply sanitizer attributes to the function. +if (SanOpts.hasOneOf(SanitizerKind::Address | SanitizerKind::KernelAddress)) + Fn->addFnAttr(llvm::Attribute::SanitizeAddress); +if (SanOpts.hasOneOf(SanitizerKind::HWAddress | + SanitizerKind::KernelHWAddress)) + Fn->addFnAttr(llvm::Attribute::SanitizeHWAddress); +if (SanOpts.has(SanitizerKind::MemTag)) + Fn->addFnAttr(llvm::Attribute::SanitizeMemTag); +if (SanOpts.has(SanitizerKind::Thread)) + Fn->addFnAttr(llvm::Attribute::SanitizeThread); +if (SanOpts.hasOneOf(SanitizerKind::Memory | SanitizerKind::KernelMemory)) + Fn->addFnAttr(llvm::Attribute::SanitizeMemory); + } if (SanOpts.has(SanitizerKind::SafeStack)) Fn->addFnAttr(llvm::Attribute::SafeStack); if (SanOpts.has(SanitizerKind::ShadowCallStack)) diff --git a/clang/lib/CodeGen/SanitizerMetadata.cpp b/clang/lib/CodeGen/SanitizerMetadata.cpp index 009965a36c396..9e26d242d3a7e 100644 --- a/clang/lib/CodeGen/SanitizerMetadata.cpp +++ b/clang/lib/CodeGen/SanitizerMetadata.cpp @@ -73,6 +73,8 @@ void SanitizerMetadata::reportGlobalToASan(llvm::GlobalVariable *GV, for (auto Attr : D.specific_attrs()) if (Attr->getMask() & SanitizerKind::Address) IsExcluded = true; + if (D.hasAttr()) +IsExcluded = true; reportGlobalToASan(GV, D.getLocation(), OS.str(
[clang] 2b55492 - [asan] Add support for disable_sanitizer_instrumentation attribute
Author: Alexander Potapenko Date: 2021-12-10T12:17:26+01:00 New Revision: 2b554920f11c8b763cd9ed9003f4e19b919b8e1f URL: https://github.com/llvm/llvm-project/commit/2b554920f11c8b763cd9ed9003f4e19b919b8e1f DIFF: https://github.com/llvm/llvm-project/commit/2b554920f11c8b763cd9ed9003f4e19b919b8e1f.diff LOG: [asan] Add support for disable_sanitizer_instrumentation attribute For ASan this will effectively serve as a synonym for __attribute__((no_sanitize("address"))) Differential Revision: https://reviews.llvm.org/D114421 Added: llvm/test/Instrumentation/AddressSanitizer/asan-disable-sanitizer-instrumentation.ll Modified: clang/docs/AddressSanitizer.rst clang/lib/CodeGen/CodeGenFunction.cpp clang/lib/CodeGen/SanitizerMetadata.cpp clang/test/CodeGen/address-safety-attr-flavors.cpp clang/test/CodeGen/asan-globals.cpp llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp Removed: diff --git a/clang/docs/AddressSanitizer.rst b/clang/docs/AddressSanitizer.rst index 06b53e2e5da0b..fe5f683580a46 100644 --- a/clang/docs/AddressSanitizer.rst +++ b/clang/docs/AddressSanitizer.rst @@ -229,6 +229,12 @@ compilers, so we suggest to use it together with The same attribute used on a global variable prevents AddressSanitizer from adding redzones around it and detecting out of bounds accesses. + +AddressSanitizer also supports +``__attribute__((disable_sanitizer_instrumentation))``. This attribute +works similar to ``__attribute__((no_sanitize("address")))``, but it also +prevents instrumentation performed by other sanitizers. + Suppressing Errors in Recompiled Code (Ignorelist) -- diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp index ed43adfab9545..f3b53c4859b2c 100644 --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -382,9 +382,6 @@ void CodeGenFunction::FinishFunction(SourceLocation EndLoc) { "__cyg_profile_func_exit"); } - if (ShouldSkipSanitizerInstrumentation()) -CurFn->addFnAttr(llvm::Attribute::DisableSanitizerInstrumentation); - // Emit debug descriptor for function end. if (CGDebugInfo *DI = getDebugInfo()) DI->EmitFunctionEnd(Builder, CurFn); @@ -766,17 +763,22 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy, Fn->addFnAttr(llvm::Attribute::NoSanitizeCoverage); } - // Apply sanitizer attributes to the function. - if (SanOpts.hasOneOf(SanitizerKind::Address | SanitizerKind::KernelAddress)) -Fn->addFnAttr(llvm::Attribute::SanitizeAddress); - if (SanOpts.hasOneOf(SanitizerKind::HWAddress | SanitizerKind::KernelHWAddress)) -Fn->addFnAttr(llvm::Attribute::SanitizeHWAddress); - if (SanOpts.has(SanitizerKind::MemTag)) -Fn->addFnAttr(llvm::Attribute::SanitizeMemTag); - if (SanOpts.has(SanitizerKind::Thread)) -Fn->addFnAttr(llvm::Attribute::SanitizeThread); - if (SanOpts.hasOneOf(SanitizerKind::Memory | SanitizerKind::KernelMemory)) -Fn->addFnAttr(llvm::Attribute::SanitizeMemory); + if (ShouldSkipSanitizerInstrumentation()) { +CurFn->addFnAttr(llvm::Attribute::DisableSanitizerInstrumentation); + } else { +// Apply sanitizer attributes to the function. +if (SanOpts.hasOneOf(SanitizerKind::Address | SanitizerKind::KernelAddress)) + Fn->addFnAttr(llvm::Attribute::SanitizeAddress); +if (SanOpts.hasOneOf(SanitizerKind::HWAddress | + SanitizerKind::KernelHWAddress)) + Fn->addFnAttr(llvm::Attribute::SanitizeHWAddress); +if (SanOpts.has(SanitizerKind::MemTag)) + Fn->addFnAttr(llvm::Attribute::SanitizeMemTag); +if (SanOpts.has(SanitizerKind::Thread)) + Fn->addFnAttr(llvm::Attribute::SanitizeThread); +if (SanOpts.hasOneOf(SanitizerKind::Memory | SanitizerKind::KernelMemory)) + Fn->addFnAttr(llvm::Attribute::SanitizeMemory); + } if (SanOpts.has(SanitizerKind::SafeStack)) Fn->addFnAttr(llvm::Attribute::SafeStack); if (SanOpts.has(SanitizerKind::ShadowCallStack)) diff --git a/clang/lib/CodeGen/SanitizerMetadata.cpp b/clang/lib/CodeGen/SanitizerMetadata.cpp index 009965a36c396..9e26d242d3a7e 100644 --- a/clang/lib/CodeGen/SanitizerMetadata.cpp +++ b/clang/lib/CodeGen/SanitizerMetadata.cpp @@ -73,6 +73,8 @@ void SanitizerMetadata::reportGlobalToASan(llvm::GlobalVariable *GV, for (auto Attr : D.specific_attrs()) if (Attr->getMask() & SanitizerKind::Address) IsExcluded = true; + if (D.hasAttr()) +IsExcluded = true; reportGlobalToASan(GV, D.getLocation(), OS.str(), D.getType(), IsDynInit, IsExcluded); } diff --git a/clang/test/CodeGen/address-safety-attr-flavors.cpp b/clang/test/CodeGen/address-safety-attr-flavors.cpp index e6d17ed2da340..ef81059db 100644 --- a/clang/test/CodeGen/address-safety-attr-flavors.cpp +++ b/clan
[clang] b0391df - [clang][Codegen] Introduce the disable_sanitizer_instrumentation attribute
Author: Alexander Potapenko Date: 2021-08-20T14:01:06+02:00 New Revision: b0391dfc737ede147e128fe877045f61fc5e4905 URL: https://github.com/llvm/llvm-project/commit/b0391dfc737ede147e128fe877045f61fc5e4905 DIFF: https://github.com/llvm/llvm-project/commit/b0391dfc737ede147e128fe877045f61fc5e4905.diff LOG: [clang][Codegen] Introduce the disable_sanitizer_instrumentation attribute The purpose of __attribute__((disable_sanitizer_instrumentation)) is to prevent all kinds of sanitizer instrumentation applied to a certain function, Objective-C method, or global variable. The no_sanitize(...) attribute drops instrumentation checks, but may still insert code preventing false positive reports. In some cases though (e.g. when building Linux kernel with -fsanitize=kernel-memory or -fsanitize=thread) the users may want to avoid any kind of instrumentation. Differential Revision: https://reviews.llvm.org/D108029 Added: clang/test/CodeGen/attr-disable-sanitizer-instrumentation.c Modified: clang/include/clang/Basic/Attr.td clang/include/clang/Basic/AttrDocs.td clang/lib/CodeGen/CodeGenFunction.cpp clang/lib/CodeGen/CodeGenFunction.h clang/test/Misc/pragma-attribute-supported-attributes-list.test llvm/docs/BitCodeFormat.rst llvm/docs/LangRef.rst llvm/include/llvm/AsmParser/LLToken.h llvm/include/llvm/Bitcode/LLVMBitCodes.h llvm/include/llvm/IR/Attributes.td llvm/lib/AsmParser/LLLexer.cpp llvm/lib/Bitcode/Reader/BitcodeReader.cpp llvm/lib/Bitcode/Writer/BitcodeWriter.cpp llvm/lib/Transforms/Utils/CodeExtractor.cpp llvm/test/Bitcode/attributes.ll llvm/test/Bitcode/compatibility.ll Removed: diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index 13d8c15001c92..f9ae1b8d86281 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -2948,6 +2948,13 @@ def NoSanitizeSpecific : InheritableAttr { let ASTNode = 0; } +def DisableSanitizerInstrumentation : InheritableAttr { + let Spellings = [Clang<"disable_sanitizer_instrumentation">]; + let Subjects = SubjectList<[Function, ObjCMethod, GlobalVar]>; + let Documentation = [DisableSanitizerInstrumentationDocs]; + let SimpleHandler = 1; +} + def CFICanonicalJumpTable : InheritableAttr { let Spellings = [Clang<"cfi_canonical_jump_table">]; let Subjects = SubjectList<[Function], ErrorDiag>; diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td index a1206347ae454..5c63c8440ad80 100644 --- a/clang/include/clang/Basic/AttrDocs.td +++ b/clang/include/clang/Basic/AttrDocs.td @@ -2602,6 +2602,18 @@ full list of supported sanitizer flags. }]; } +def DisableSanitizerInstrumentationDocs : Documentation { + let Category = DocCatFunction; + let Content = [{ +Use the ``disable_sanitizer_instrumentation`` attribute on a function, +Objective-C method, or global variable, to specify that no sanitizer +instrumentation should be applied. + +This is not the same as ``__attribute__((no_sanitize(...)))``, which depending +on the tool may still insert instrumentation to prevent false positive reports. + }]; +} + def NoSanitizeAddressDocs : Documentation { let Category = DocCatFunction; // This function has multiple distinct spellings, and so it requires a custom diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp index dca42045325df..e3a66318c086c 100644 --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -381,6 +381,9 @@ void CodeGenFunction::FinishFunction(SourceLocation EndLoc) { "__cyg_profile_func_exit"); } + if (ShouldSkipSanitizerInstrumentation()) +CurFn->addFnAttr(llvm::Attribute::DisableSanitizerInstrumentation); + // Emit debug descriptor for function end. if (CGDebugInfo *DI = getDebugInfo()) DI->EmitFunctionEnd(Builder, CurFn); @@ -519,6 +522,12 @@ bool CodeGenFunction::ShouldInstrumentFunction() { return true; } +bool CodeGenFunction::ShouldSkipSanitizerInstrumentation() { + if (!CurFuncDecl) +return false; + return CurFuncDecl->hasAttr(); +} + /// ShouldXRayInstrument - Return true if the current function should be /// instrumented with XRay nop sleds. bool CodeGenFunction::ShouldXRayInstrumentFunction() const { diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index 0baa45e6b9f27..f74bff91f007c 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -2286,6 +2286,10 @@ class CodeGenFunction : public CodeGenTypeCache { /// instrumented with __cyg_profile_func_* calls bool ShouldInstrumentFunction(); + /// ShouldSkipSanitizerInstrumentation - Return true if the current function + /// should not be instrumented with sanitizers. + bool ShouldSkipSanitizerInstrumen
[clang] 8dc7dcd - [msan] Add support for disable_sanitizer_instrumentation attribute
Author: Alexander Potapenko Date: 2021-08-20T15:11:26+02:00 New Revision: 8dc7dcdca1e0d0ce4e39305272c8021a1aed07ed URL: https://github.com/llvm/llvm-project/commit/8dc7dcdca1e0d0ce4e39305272c8021a1aed07ed DIFF: https://github.com/llvm/llvm-project/commit/8dc7dcdca1e0d0ce4e39305272c8021a1aed07ed.diff LOG: [msan] Add support for disable_sanitizer_instrumentation attribute Unlike __attribute__((no_sanitize("memory"))), this one will cause MSan to skip the entire function during instrumentation. Depends on https://reviews.llvm.org/D108029 Differential Revision: https://reviews.llvm.org/D108199 Added: clang/test/CodeGen/sanitize-memory-disable.c Modified: clang/docs/MemorySanitizer.rst llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp Removed: diff --git a/clang/docs/MemorySanitizer.rst b/clang/docs/MemorySanitizer.rst index 3ba5ce5bed3e..c6fc9407ea15 100644 --- a/clang/docs/MemorySanitizer.rst +++ b/clang/docs/MemorySanitizer.rst @@ -85,6 +85,15 @@ particular function. MemorySanitizer may still instrument such functions to avoid false positives. This attribute may not be supported by other compilers, so we suggest to use it together with ``__has_feature(memory_sanitizer)``. +``__attribute__((disable_sanitizer_instrumentation))`` + + +The ``disable_sanitizer_instrumentation`` attribute can be applied to functions +to prevent all kinds of instrumentation. As a result, it may introduce false +positives and therefore should be used with care, and only if absolutely +required; for example for certain code that cannot tolerate any instrumentation +and resulting side-effects. This attribute overrides ``no_sanitize("memory")``. + Ignorelist -- diff --git a/clang/test/CodeGen/sanitize-memory-disable.c b/clang/test/CodeGen/sanitize-memory-disable.c new file mode 100644 index ..5bf4dc9c185e --- /dev/null +++ b/clang/test/CodeGen/sanitize-memory-disable.c @@ -0,0 +1,58 @@ +// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck -check-prefixes CHECK,WITHOUT %s +// RUN: %clang_cc1 -emit-llvm -o - %s -fsanitize=memory | FileCheck -check-prefixes CHECK,MSAN %s +// RUN: %clang_cc1 -emit-llvm -o - %s -fsanitize=kernel-memory | FileCheck -check-prefixes CHECK,KMSAN %s + +// Instrumented function. +// MSan uses memset(addr, -1, size) to poison allocas and stores shadow of the return value in +// __msan_retval_tls. KMSAN uses __msan_poison_alloca() to poison allocas and calls +// __msan_get_context_state() at function prologue to access the task context struct (including the +// shadow of the return value). +// +// CHECK-LABEL: i32 @instrumented1 +// KMSAN: __msan_get_context_state +// WITHOUT-NOT: __msan_poison_alloca +// WITHOUT-NOT: @llvm.memset +// MSAN: @llvm.memset{{.*}}({{.*}}, i8 -1 +// KMSAN: __msan_poison_alloca +// WITHOUT-NOT: __msan_retval_tls +// MSAN: __msan_retval_tls +// CHECK: ret i32 +int instrumented1(int *a) { + volatile char buf[8]; + return *a; +} + +// Function with no_sanitize("memory")/no_sanitize("kernel-memory"): no shadow propagation, but +// unpoisons memory to prevent false positives. +// MSan uses memset(addr, 0, size) to unpoison locals, KMSAN uses __msan_unpoison_alloca(). Both +// tools still access the retval shadow to write 0 to it. +// +// CHECK-LABEL: i32 @no_false_positives1 +// KMSAN: __msan_get_context_state +// WITHOUT-NOT: __msan_unpoison_alloca +// WITHOUT-NOT: @llvm.memset +// MSAN: @llvm.memset{{.*}}({{.*}}, i8 0 +// KMSAN: __msan_unpoison_alloca +// WITHOUT-NOT: __msan_retval_tls +// MSAN: __msan_retval_tls +// CHECK: ret i32 +__attribute__((no_sanitize("memory"))) __attribute__((no_sanitize("kernel-memory"))) int no_false_positives1(int *a) { + volatile char buf[8]; + return *a; +} + +// Function with disable_sanitizer_instrumentation: no instrumentation at all. +// +// CHECK-LABEL: i32 @no_instrumentation1 +// KMSAN-NOT: __msan_get_context_state +// WITHOUT-NOT: __msan_poison_alloca +// WITHOUT-NOT: @llvm.memset +// MSAN-NOT: @llvm.memset{{.*}}({{.*}}, i8 0 +// KMSAN-NOT: __msan_unpoison_alloca +// WITHOUT-NOT: __msan_retval_tls +// MSAN-NOT: __msan_retval_tls +// CHECK: ret i32 +__attribute__((disable_sanitizer_instrumentation)) int no_instrumentation1(int *a) { + volatile char buf[8]; + return *a; +} diff --git a/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp b/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp index 7e6709be4bbf..9b4cc9c46f45 100644 --- a/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp @@ -5330,6 +5330,9 @@ bool MemorySanitizer::sanitizeFunction(Function &F, TargetLibraryInfo &TLI) { if (!CompileKernel && F.getName() == kMsanModuleCtorName) return false; + if (F.hasFnAttribute(Attribute::DisableSanitizerInstrumentation)) +return false; + Me
[clang] 417a49e - [msan] Hotfix clang/test/CodeGen/sanitize-memory-disable.c
Author: Alexander Potapenko Date: 2021-08-20T16:00:25+02:00 New Revision: 417a49e78e730c964c60840110455c29fb562ee0 URL: https://github.com/llvm/llvm-project/commit/417a49e78e730c964c60840110455c29fb562ee0 DIFF: https://github.com/llvm/llvm-project/commit/417a49e78e730c964c60840110455c29fb562ee0.diff LOG: [msan] Hotfix clang/test/CodeGen/sanitize-memory-disable.c Because KMSAN is not supported on many architectures, explicitly build the test with -target x86_64-linux-gnu. Fixes the 'unsupported architecture' and 'unsupported operating system' errors reported by the clang-armv7-quick (https://lab.llvm.org/buildbot#builders/171/builds/2595) and llvm-clang-x86_64-sie-ubuntu-fast (https://lab.llvm.org/buildbot#builders/139/builds/9079) builders. Differential Revision: https://reviews.llvm.org/D108465 Added: Modified: clang/test/CodeGen/sanitize-memory-disable.c Removed: diff --git a/clang/test/CodeGen/sanitize-memory-disable.c b/clang/test/CodeGen/sanitize-memory-disable.c index 5bf4dc9c185e..da3593ac973b 100644 --- a/clang/test/CodeGen/sanitize-memory-disable.c +++ b/clang/test/CodeGen/sanitize-memory-disable.c @@ -1,6 +1,6 @@ -// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck -check-prefixes CHECK,WITHOUT %s -// RUN: %clang_cc1 -emit-llvm -o - %s -fsanitize=memory | FileCheck -check-prefixes CHECK,MSAN %s -// RUN: %clang_cc1 -emit-llvm -o - %s -fsanitize=kernel-memory | FileCheck -check-prefixes CHECK,KMSAN %s +// RUN: %clang -target x86_64-linux-gnu -S -emit-llvm -o - %s | FileCheck -check-prefixes CHECK,WITHOUT %s +// RUN: %clang -target x86_64-linux-gnu -S -emit-llvm -o - %s -fsanitize=memory | FileCheck -check-prefixes CHECK,MSAN %s +// RUN: %clang -target x86_64-linux-gnu -S -emit-llvm -o - %s -fsanitize=kernel-memory | FileCheck -check-prefixes CHECK,KMSAN %s // Instrumented function. // MSan uses memset(addr, -1, size) to poison allocas and stores shadow of the return value in ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 8300d52 - [tsan] Add support for disable_sanitizer_instrumentation attribute
Author: Alexander Potapenko Date: 2021-08-23T12:38:33+02:00 New Revision: 8300d52e8cbf757192d6b66efa537e15376bf756 URL: https://github.com/llvm/llvm-project/commit/8300d52e8cbf757192d6b66efa537e15376bf756 DIFF: https://github.com/llvm/llvm-project/commit/8300d52e8cbf757192d6b66efa537e15376bf756.diff LOG: [tsan] Add support for disable_sanitizer_instrumentation attribute Unlike __attribute__((no_sanitize("thread"))), this one will cause TSan to skip the entire function during instrumentation. Depends on https://reviews.llvm.org/D108029 Differential Revision: https://reviews.llvm.org/D108202 Added: clang/test/CodeGen/sanitize-thread-disable.c Modified: clang/docs/ThreadSanitizer.rst llvm/lib/Transforms/Instrumentation/ThreadSanitizer.cpp Removed: diff --git a/clang/docs/ThreadSanitizer.rst b/clang/docs/ThreadSanitizer.rst index 92cc9392955cc..98d5307d824f9 100644 --- a/clang/docs/ThreadSanitizer.rst +++ b/clang/docs/ThreadSanitizer.rst @@ -100,6 +100,16 @@ instruments such functions to avoid false positives and provide meaningful stack traces. This attribute may not be supported by other compilers, so we suggest to use it together with ``__has_feature(thread_sanitizer)``. +``__attribute__((disable_sanitizer_instrumentation))`` + + +The ``disable_sanitizer_instrumentation`` attribute can be applied to functions +to prevent all kinds of instrumentation. As a result, it may introduce false +positives and incorrect stack traces. Therefore, it should be used with care, +and only if absolutely required; for example for certain code that cannot +tolerate any instrumentation and resulting side-effects. This attribute +overrides ``no_sanitize("thread")``. + Ignorelist -- diff --git a/clang/test/CodeGen/sanitize-thread-disable.c b/clang/test/CodeGen/sanitize-thread-disable.c new file mode 100644 index 0..d3ec1425e7821 --- /dev/null +++ b/clang/test/CodeGen/sanitize-thread-disable.c @@ -0,0 +1,57 @@ +// RUN: %clang -target x86_64-linux-gnu -S -emit-llvm -o - %s | FileCheck -check-prefixes CHECK,WITHOUT %s +// RUN: %clang -target x86_64-linux-gnu -S -emit-llvm -o - %s -fsanitize=thread | FileCheck -check-prefixes CHECK,TSAN %s + +#include + +// Instrumented function. +// TSan inserts calls to __tsan_func_entry() and __tsan_func_exit() to prologue/epilogue. +// Non-atomic loads are instrumented with __tsan_readXXX(), atomic loads - with +// __tsan_atomicXXX_load(). +// +// CHECK-LABEL: @instrumented1 +// TSAN: call void @__tsan_func_entry +// WITHOUT-NOT: call void @__tsan_func_entry +// TSAN: call void @__tsan_read4 +// WITHOUT-NOT: call void @__tsan_read4 +// TSAN: call i32 @__tsan_atomic32_load +// WITHOUT-NOT: call i32 @__tsan_atomic32_load +// TSAN: call void @__tsan_func_exit +// WITHOUT-NOT: call void @__tsan_func_exit +// CHECK: ret i32 +int instrumented1(int *a, _Atomic int *b) { + return *a + atomic_load(b); +} + +// Function with no_sanitize("thread"). +// TSan only inserts instrumentation necessary to prevent false positives: calls are inserted for +// function entry/exit and atomics, but not plain memory accesses. +// +// CHECK-LABEL: @no_false_positives1 +// TSAN: call void @__tsan_func_entry +// WITHOUT-NOT: call void @__tsan_func_entry +// TSAN-NOT: call void @__tsan_read4 +// WITHOUT-NOT: call void @__tsan_read4 +// TSAN: call i32 @__tsan_atomic32_load +// WITHOUT-NOT: call i32 @__tsan_atomic32_load +// TSAN: call void @__tsan_func_exit +// WITHOUT-NOT: call void @__tsan_func_exit +// CHECK: ret i32 +__attribute__((no_sanitize("thread"))) int no_false_positives1(int *a, _Atomic int *b) { + return *a + atomic_load(b); +} + +// Function with disable_sanitizer_instrumentation: no instrumentation at all. +// +// CHECK-LABEL: @no_instrumentation1 +// TSAN-NOT: call void @__tsan_func_entry +// WITHOUT-NOT: call void @__tsan_func_entry +// TSAN-NOT: call void @__tsan_read4 +// WITHOUT-NOT: call void @__tsan_read4 +// TSAN-NOT: call i32 @__tsan_atomic32_load +// WITHOUT-NOT: call i32 @__tsan_atomic32_load +// TSAN-NOT: call void @__tsan_func_exit +// WITHOUT-NOT: call void @__tsan_func_exit +// CHECK: ret i32 +__attribute__((disable_sanitizer_instrumentation)) int no_instrumentation1(int *a, _Atomic int *b) { + return *a + atomic_load(b); +} diff --git a/llvm/lib/Transforms/Instrumentation/ThreadSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/ThreadSanitizer.cpp index 87fdcc9114f44..714e21dc82bb4 100644 --- a/llvm/lib/Transforms/Instrumentation/ThreadSanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/ThreadSanitizer.cpp @@ -562,6 +562,12 @@ bool ThreadSanitizer::sanitizeFunction(Function &F, // all. if (F.hasFnAttribute(Attribute::Naked)) return false; + + // __attribute__(disable_sanitizer_instrumentation) prevents all kinds of + // instrumentation. + if (F.hasFnAttribute(Att
[clang] cdb3916 - [tsan] Do not include from sanitize-thread-disable.c
Author: Alexander Potapenko Date: 2021-08-23T16:21:43+02:00 New Revision: cdb391698bb29fcbb9156604793121fdd73d3a89 URL: https://github.com/llvm/llvm-project/commit/cdb391698bb29fcbb9156604793121fdd73d3a89 DIFF: https://github.com/llvm/llvm-project/commit/cdb391698bb29fcbb9156604793121fdd73d3a89.diff LOG: [tsan] Do not include from sanitize-thread-disable.c Looks like non-x86 bots are unhappy with inclusion of e.g.: clang-armv7-vfpv3-2stage - https://lab.llvm.org/buildbot/#/builders/182/builds/626 clang-ppc64le-linux - https://lab.llvm.org/buildbot/#/builders/76/builds/3619 llvm-clang-win-x-armv7l - https://lab.llvm.org/buildbot/#/builders/60/builds/4514 It seems to be unnecessary, just remove it and replace atomic_load() calls with dereferences of _Atomic*. Differential Revision: https://reviews.llvm.org/D108555 Added: Modified: clang/test/CodeGen/sanitize-thread-disable.c Removed: diff --git a/clang/test/CodeGen/sanitize-thread-disable.c b/clang/test/CodeGen/sanitize-thread-disable.c index d3ec1425e782..48a345928f6d 100644 --- a/clang/test/CodeGen/sanitize-thread-disable.c +++ b/clang/test/CodeGen/sanitize-thread-disable.c @@ -1,8 +1,6 @@ // RUN: %clang -target x86_64-linux-gnu -S -emit-llvm -o - %s | FileCheck -check-prefixes CHECK,WITHOUT %s // RUN: %clang -target x86_64-linux-gnu -S -emit-llvm -o - %s -fsanitize=thread | FileCheck -check-prefixes CHECK,TSAN %s -#include - // Instrumented function. // TSan inserts calls to __tsan_func_entry() and __tsan_func_exit() to prologue/epilogue. // Non-atomic loads are instrumented with __tsan_readXXX(), atomic loads - with @@ -19,7 +17,7 @@ // WITHOUT-NOT: call void @__tsan_func_exit // CHECK: ret i32 int instrumented1(int *a, _Atomic int *b) { - return *a + atomic_load(b); + return *a + *b; } // Function with no_sanitize("thread"). @@ -37,7 +35,7 @@ int instrumented1(int *a, _Atomic int *b) { // WITHOUT-NOT: call void @__tsan_func_exit // CHECK: ret i32 __attribute__((no_sanitize("thread"))) int no_false_positives1(int *a, _Atomic int *b) { - return *a + atomic_load(b); + return *a + *b; } // Function with disable_sanitizer_instrumentation: no instrumentation at all. @@ -53,5 +51,5 @@ __attribute__((no_sanitize("thread"))) int no_false_positives1(int *a, _Atomic i // WITHOUT-NOT: call void @__tsan_func_exit // CHECK: ret i32 __attribute__((disable_sanitizer_instrumentation)) int no_instrumentation1(int *a, _Atomic int *b) { - return *a + atomic_load(b); + return *a + *b; } ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] FEAT: 1 byte for "true" & "false" (PR #138713)
ramosian-glider wrote: > Yeah! you are right that the size depends on the variable, but I never said > to create a variable. > Suppose I have two functions performing same process but one is returning > bool and other one is returning int. > > 1. bool fnc1() { return (_Bool)true; } > 2. int fnc2(){ return true; } > > Can you please tell me which of the above 2 function will be more efficient? Again, in this case the "efficiency" of these functions does not depend on how you declare true and false, but rather on what return type each function has. But the impact of type change is also questionable. Per modern calling conventions, the return value of a function is stored in a CPU register, and the size of that register is usually 4 or 8 bytes. Even if one decides to return a 1-byte value, there won't be much difference for the CPU. (Well, on x86 you can return the 1-byte value in AL, but this won't lead to faster code). > If this is also the case with Clang, then my work is done here. Yes, this is also the case. https://github.com/llvm/llvm-project/pull/138713 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits