https://github.com/kees created https://github.com/llvm/llvm-project/pull/162428
As fixed in commits llvm/llvm-project@913f7e9, llvm/llvm-project@4a8b124, and llvm/llvm-project@4eef2e3, also fix the stack-depth tracking code to use InstrumentationIRBuilder, and set the Call's Debug location to EntryLoc. https://github.com/ClangBuiltLinux/linux/issues/2125 cc @nathanchance @melver @JustinStitt @bwendling >From b52f9fee77502edc299e73b799f1691ce8978f3d Mon Sep 17 00:00:00 2001 From: Kees Cook <[email protected]> Date: Tue, 7 Oct 2025 09:32:38 -0700 Subject: [PATCH] [sancov] Fix stack-depth tracking to use debug locations As fixed in commits llvm/llvm-project@913f7e9, llvm/llvm-project@4a8b124, and llvm/llvm-project@4eef2e3, also fix the stack-depth tracking code to use InstrumentationIRBuilder, and set the Call's Debug location to EntryLoc. https://github.com/ClangBuiltLinux/linux/issues/2125 --- ...sanitizer-coverage-stack-depth-debug-loc.c | 40 +++++++++++++++++++ .../Instrumentation/SanitizerCoverage.cpp | 9 +++-- 2 files changed, 46 insertions(+), 3 deletions(-) create mode 100644 clang/test/CodeGen/sanitizer-coverage-stack-depth-debug-loc.c diff --git a/clang/test/CodeGen/sanitizer-coverage-stack-depth-debug-loc.c b/clang/test/CodeGen/sanitizer-coverage-stack-depth-debug-loc.c new file mode 100644 index 0000000000000..33791dabcdca8 --- /dev/null +++ b/clang/test/CodeGen/sanitizer-coverage-stack-depth-debug-loc.c @@ -0,0 +1,40 @@ +// Test that SanitizerCoverage preserves debug locations when inserting stack depth tracking +// This is a regression test for GitHub issue ClangBuiltLinux/linux#2125 +// +// The bug was that IRBuilder<> was used instead of InstrumentationIRBuilder in SanitizerCoverage, +// causing inserted instructions to lack !dbg metadata. This caused LTO builds with debug info +// to fail verification with: +// "inlinable function call in a function with debug info must have a !dbg location" +// +// Test the lowest-stack tracking path (default stack-depth mode) +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -o - %s \ +// RUN: -fsanitize-coverage-type=1 -fsanitize-coverage-stack-depth -debug-info-kind=limited \ +// RUN: | FileCheck %s --check-prefix=CHECK-STORE +// +// Test the callback path (stack-depth with callback-min threshold) +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -o - %s \ +// RUN: -fsanitize-coverage-type=1 -mllvm -sanitizer-coverage-stack-depth \ +// RUN: -mllvm -sanitizer-coverage-stack-depth-callback-min=1 -debug-info-kind=limited \ +// RUN: | FileCheck %s --check-prefix=CHECK-CALLBACK +// +// Verify the store to __sancov_lowest_stack has a debug location +// CHECK-STORE: store i64 %{{.*}}, ptr @__sancov_lowest_stack, align 8, !dbg !{{[0-9]+}}, {{.*}}!nosanitize +// +// Verify the call to __sanitizer_cov_stack_depth has a debug location +// CHECK-CALLBACK: call void @__sanitizer_cov_stack_depth(){{.*}}, !dbg !{{[0-9]+}} + +extern void external_func(void); + +// Mark as always_inline to ensure the bug condition is met +__attribute__((always_inline)) +static inline void inline_helper(void) { + external_func(); +} + +void foo(int a) { + int local[4]; // Stack allocation to trigger stack depth tracking + if (a > 0) { + inline_helper(); + } + local[0] = a; +} diff --git a/llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp b/llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp index 5b8ea1547ca2f..5dbd0ec2a0e27 100644 --- a/llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp +++ b/llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp @@ -1084,7 +1084,7 @@ void ModuleSanitizerCoverage::InjectCoverageAtBlock(Function &F, BasicBlock &BB, auto ThenTerm = SplitBlockAndInsertIfThen( IRB.CreateIsNull(Load), &*IP, false, MDBuilder(IRB.getContext()).createUnlikelyBranchWeights()); - IRBuilder<> ThenIRB(ThenTerm); + InstrumentationIRBuilder ThenIRB(ThenTerm); auto Store = ThenIRB.CreateStore(ConstantInt::getTrue(Int1Ty), FlagPtr); Load->setNoSanitizeMetadata(); Store->setNoSanitizeMetadata(); @@ -1131,7 +1131,10 @@ void ModuleSanitizerCoverage::InjectCoverageAtBlock(Function &F, BasicBlock &BB, EstimatedStackSize >= Options.StackDepthCallbackMin) { if (InsertBefore) IRB.SetInsertPoint(InsertBefore); - IRB.CreateCall(SanCovStackDepthCallback)->setCannotMerge(); + auto Call = IRB.CreateCall(SanCovStackDepthCallback); + if (EntryLoc) + Call->setDebugLoc(EntryLoc); + Call->setCannotMerge(); } } else { // Check stack depth. If it's the deepest so far, record it. @@ -1144,7 +1147,7 @@ void ModuleSanitizerCoverage::InjectCoverageAtBlock(Function &F, BasicBlock &BB, auto ThenTerm = SplitBlockAndInsertIfThen( IsStackLower, &*IP, false, MDBuilder(IRB.getContext()).createUnlikelyBranchWeights()); - IRBuilder<> ThenIRB(ThenTerm); + InstrumentationIRBuilder ThenIRB(ThenTerm); auto Store = ThenIRB.CreateStore(FrameAddrInt, SanCovLowestStack); LowestStack->setNoSanitizeMetadata(); Store->setNoSanitizeMetadata(); _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
