[PATCH] D133157: Add -sanitizer-coverage-control-flow

2022-09-02 Thread Navid Emamdoost via Phabricator via cfe-commits
Navidem updated this revision to Diff 457734.
Navidem added a comment.
Herald added subscribers: cfe-commits, ormris, MaskRay.
Herald added a project: clang.

Updated docs, lit test, and added clang option.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D133157/new/

https://reviews.llvm.org/D133157

Files:
  clang/docs/SanitizerCoverage.rst
  clang/include/clang/Basic/CodeGenOptions.def
  clang/include/clang/Basic/CodeGenOptions.h
  clang/include/clang/Driver/Options.td
  clang/lib/CodeGen/BackendUtil.cpp
  clang/lib/Driver/SanitizerArgs.cpp
  llvm/include/llvm/Transforms/Instrumentation.h
  llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp
  llvm/test/Instrumentation/SanitizerCoverage/control-flow.ll

Index: llvm/test/Instrumentation/SanitizerCoverage/control-flow.ll
===
--- /dev/null
+++ llvm/test/Instrumentation/SanitizerCoverage/control-flow.ll
@@ -0,0 +1,22 @@
+; Test -sanitizer-coverage-control-flow
+; RUN: opt < %s -passes='module(sancov-module)' -sanitizer-coverage-level=3 -sanitizer-coverage-control-flow -S | FileCheck %s
+
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-unknown-linux-gnu"
+define void @foo(i32* %a) sanitize_address {
+entry:
+  %tobool = icmp eq i32* %a, null
+  br i1 %tobool, label %if.end, label %if.then
+
+  if.then:  ; preds = %entry
+  store i32 0, i32* %a, align 4
+  call void @foo(i32* %a)
+  br label %if.end
+
+  if.end:   ; preds = %entry, %if.then
+  ret void
+}
+
+; CHECK: private constant [17 x i64*] [{{.*}}@foo{{.*}}blockaddress{{.*}}blockaddress{{.*}}blockaddress{{.*}}blockaddress{{.*}}blockaddress{{.*}}blockaddress{{.*}}blockaddress{{.*}}@foo{{.*}}null{{.*}}null], section "__sancov_cfs", comdat($foo), align 8
+; CHECK:  @__start___sancov_cfs = extern_weak hidden global i64*
+; CHECK-NEXT: @__stop___sancov_cfs = extern_weak hidden global i64*
Index: llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp
===
--- llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp
+++ llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp
@@ -80,6 +80,7 @@
 const char SanCovCountersSectionName[] = "sancov_cntrs";
 const char SanCovBoolFlagSectionName[] = "sancov_bools";
 const char SanCovPCsSectionName[] = "sancov_pcs";
+const char SanCovCFsSectionName[] = "sancov_cfs";
 
 const char SanCovLowestStackName[] = "__sancov_lowest_stack";
 
@@ -147,6 +148,10 @@
   cl::desc("max stack depth tracing"),
   cl::Hidden, cl::init(false));
 
+static cl::opt ClCollectCF("sanitizer-coverage-control-flow",
+  cl::desc("collect control flow for each function"),
+  cl::Hidden, cl::init(false));
+
 namespace {
 
 SanitizerCoverageOptions getOptions(int LegacyCoverageLevel) {
@@ -193,6 +198,7 @@
   !Options.Inline8bitCounters && !Options.StackDepth &&
   !Options.InlineBoolFlag && !Options.TraceLoads && !Options.TraceStores)
 Options.TracePCGuard = true; // TracePCGuard is default.
+  Options.CollectControlFlow |= ClCollectCF;
   return Options;
 }
 
@@ -212,6 +218,7 @@
 PostDomTreeCallback PDTCallback);
 
 private:
+  void CollectFunctionControlFlow(Function &F);
   void instrumentFunction(Function &F, DomTreeCallback DTCallback,
   PostDomTreeCallback PDTCallback);
   void InjectCoverageForIndirectCalls(Function &F,
@@ -270,6 +277,7 @@
   GlobalVariable *Function8bitCounterArray;  // for inline-8bit-counters.
   GlobalVariable *FunctionBoolArray; // for inline-bool-flag.
   GlobalVariable *FunctionPCsArray;  // for pc-table.
+  GlobalVariable *FunctionCFsArray;  // for control flow table
   SmallVector GlobalsToAppendToUsed;
   SmallVector GlobalsToAppendToCompilerUsed;
 
@@ -378,6 +386,7 @@
   Function8bitCounterArray = nullptr;
   FunctionBoolArray = nullptr;
   FunctionPCsArray = nullptr;
+  FunctionCFsArray = nullptr;
   IntptrTy = Type::getIntNTy(*C, DL->getPointerSizeInBits());
   IntptrPtrTy = PointerType::getUnqual(IntptrTy);
   Type *VoidTy = Type::getVoidTy(*C);
@@ -502,6 +511,10 @@
 IRBuilder<> IRBCtor(Ctor->getEntryBlock().getTerminator());
 IRBCtor.CreateCall(InitFunction, {SecStartEnd.first, SecStartEnd.second});
   }
+
+  if (Options.CollectControlFlow)
+CreateSecStartEnd(M, SanCovCFsSectionName, IntptrPtrTy);
+
   appendToUsed(M, GlobalsToAppendToUsed);
   appendToCompilerUsed(M, GlobalsToAppendToCompilerUsed);
   return true;
@@ -671,6 +684,9 @@
 }
   }
 
+  if (Options.CollectControlFlow)
+CollectFunctionControlFlow(F);
+
   InjectCoverage(F, BlocksToInstrume

[PATCH] D133157: Add -sanitizer-coverage-control-flow

2022-09-02 Thread Navid Emamdoost via Phabricator via cfe-commits
Navidem added inline comments.



Comment at: llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp:1055
+  for (auto &BB: F) {
+// blockaddress may not be used on function's entry block.
+if (&BB == &F.getEntryBlock())

Navidem wrote:
> kcc wrote:
> > vitalybuka wrote:
> > > what does happen?
> > "can not" ?
> Actually I started with "can not", but saw the error message from opt saying 
> "may not". Changing anyways :)
Gives invalid IR error if `blockaddress` is used with function entry as arg.



Comment at: llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp:1057
+if (&BB == &F.getEntryBlock())
+  CFs.push_back((Constant *)IRB.CreatePointerCast(&F, IntptrPtrTy));
+else

vitalybuka wrote:
> static_cast or dyn_cast
Please check lines 739-746. This usage pattern is already there. Should we 
change those as well?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D133157/new/

https://reviews.llvm.org/D133157

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D133157: Add -sanitizer-coverage-control-flow

2022-09-02 Thread Navid Emamdoost via Phabricator via cfe-commits
Navidem added inline comments.



Comment at: llvm/test/Instrumentation/SanitizerCoverage/control-flow.ll:2
+; Test -sanitizer-coverage-control-flow
+; RUN: opt < %s -passes='module(sancov-module)' -sanitizer-coverage-level=3 
-sanitizer-coverage-control-flow -S | FileCheck %s
+

vitalybuka wrote:
> you don't have to, but may try to generate test with
> llvm/utils/update_test_checks.py --opt-binary bin/opt 
> llvm/test/Instrumentation/SanitizerCoverage/control-flow.ll
> 
> It could be reasonable, or not
Thanks! I tried it and it added many more checks, which does not seem very 
useful? Please let me know if you see some value in having these:

```
+; CHECK-LABEL: @foo(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:call void @__sanitizer_cov_trace_pc_guard(i32* getelementptr 
inbounds ([3 x i32], [3 x i32]* @__sancov_gen_.1, i32 0, i32 0)) 
#[[ATTR2:[0-9]+]]
+; CHECK-NEXT:[[TOBOOL:%.*]] = icmp eq i32* [[A:%.*]], null
+; CHECK-NEXT:br i1 [[TOBOOL]], label [[ENTRY_IF_END_CRIT_EDGE:%.*]], label 
[[IF_THEN:%.*]]
+; CHECK:   entry.if.end_crit_edge:
+; CHECK-NEXT:call void @__sanitizer_cov_trace_pc_guard(i32* inttoptr (i64 
add (i64 ptrtoint ([3 x i32]* @__sancov_gen_.1 to i64), i64 4) to i32*)) 
#[[ATTR2]]
+; CHECK-NEXT:br label [[IF_END:%.*]]
+; CHECK:   if.then:
+; CHECK-NEXT:call void @__sanitizer_cov_trace_pc_guard(i32* inttoptr (i64 
add (i64 ptrtoint ([3 x i32]* @__sancov_gen_.1 to i64), i64 8) to i32*)) 
#[[ATTR2]]
+; CHECK-NEXT:store i32 0, i32* [[A]], align 4
+; CHECK-NEXT:call void @foo(i32* [[A]])
+; CHECK-NEXT:br label [[IF_END]]
+; CHECK:   if.end:
+; CHECK-NEXT:ret void
+;

```


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D133157/new/

https://reviews.llvm.org/D133157

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D133157: Add -sanitizer-coverage-control-flow

2022-09-02 Thread Navid Emamdoost via Phabricator via cfe-commits
Navidem updated this revision to Diff 457754.
Navidem added a comment.
Herald added a project: Sanitizers.
Herald added a subscriber: Sanitizers.

Added an initial run-time test


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D133157/new/

https://reviews.llvm.org/D133157

Files:
  clang/docs/SanitizerCoverage.rst
  clang/include/clang/Basic/CodeGenOptions.def
  clang/include/clang/Basic/CodeGenOptions.h
  clang/include/clang/Driver/Options.td
  clang/lib/CodeGen/BackendUtil.cpp
  clang/lib/Driver/SanitizerArgs.cpp
  
compiler-rt/test/sanitizer_common/TestCases/sanitizer_coverage_control_flow.cpp
  llvm/include/llvm/Transforms/Instrumentation.h
  llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp
  llvm/test/Instrumentation/SanitizerCoverage/control-flow.ll

Index: llvm/test/Instrumentation/SanitizerCoverage/control-flow.ll
===
--- /dev/null
+++ llvm/test/Instrumentation/SanitizerCoverage/control-flow.ll
@@ -0,0 +1,22 @@
+; Test -sanitizer-coverage-control-flow
+; RUN: opt < %s -passes='module(sancov-module)' -sanitizer-coverage-level=3 -sanitizer-coverage-control-flow -S | FileCheck %s
+
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-unknown-linux-gnu"
+define void @foo(i32* %a) sanitize_address {
+entry:
+  %tobool = icmp eq i32* %a, null
+  br i1 %tobool, label %if.end, label %if.then
+
+  if.then:  ; preds = %entry
+  store i32 0, i32* %a, align 4
+  call void @foo(i32* %a)
+  br label %if.end
+
+  if.end:   ; preds = %entry, %if.then
+  ret void
+}
+
+; CHECK: private constant [17 x i64*] [{{.*}}@foo{{.*}}blockaddress{{.*}}blockaddress{{.*}}blockaddress{{.*}}blockaddress{{.*}}blockaddress{{.*}}blockaddress{{.*}}blockaddress{{.*}}@foo{{.*}}null{{.*}}null], section "__sancov_cfs", comdat($foo), align 8
+; CHECK:  @__start___sancov_cfs = extern_weak hidden global i64*
+; CHECK-NEXT: @__stop___sancov_cfs = extern_weak hidden global i64*
Index: llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp
===
--- llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp
+++ llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp
@@ -80,6 +80,7 @@
 const char SanCovCountersSectionName[] = "sancov_cntrs";
 const char SanCovBoolFlagSectionName[] = "sancov_bools";
 const char SanCovPCsSectionName[] = "sancov_pcs";
+const char SanCovCFsSectionName[] = "sancov_cfs";
 
 const char SanCovLowestStackName[] = "__sancov_lowest_stack";
 
@@ -147,6 +148,10 @@
   cl::desc("max stack depth tracing"),
   cl::Hidden, cl::init(false));
 
+static cl::opt ClCollectCF("sanitizer-coverage-control-flow",
+  cl::desc("collect control flow for each function"),
+  cl::Hidden, cl::init(false));
+
 namespace {
 
 SanitizerCoverageOptions getOptions(int LegacyCoverageLevel) {
@@ -193,6 +198,7 @@
   !Options.Inline8bitCounters && !Options.StackDepth &&
   !Options.InlineBoolFlag && !Options.TraceLoads && !Options.TraceStores)
 Options.TracePCGuard = true; // TracePCGuard is default.
+  Options.CollectControlFlow |= ClCollectCF;
   return Options;
 }
 
@@ -212,6 +218,7 @@
 PostDomTreeCallback PDTCallback);
 
 private:
+  void CollectFunctionControlFlow(Function &F);
   void instrumentFunction(Function &F, DomTreeCallback DTCallback,
   PostDomTreeCallback PDTCallback);
   void InjectCoverageForIndirectCalls(Function &F,
@@ -270,6 +277,7 @@
   GlobalVariable *Function8bitCounterArray;  // for inline-8bit-counters.
   GlobalVariable *FunctionBoolArray; // for inline-bool-flag.
   GlobalVariable *FunctionPCsArray;  // for pc-table.
+  GlobalVariable *FunctionCFsArray;  // for control flow table
   SmallVector GlobalsToAppendToUsed;
   SmallVector GlobalsToAppendToCompilerUsed;
 
@@ -378,6 +386,7 @@
   Function8bitCounterArray = nullptr;
   FunctionBoolArray = nullptr;
   FunctionPCsArray = nullptr;
+  FunctionCFsArray = nullptr;
   IntptrTy = Type::getIntNTy(*C, DL->getPointerSizeInBits());
   IntptrPtrTy = PointerType::getUnqual(IntptrTy);
   Type *VoidTy = Type::getVoidTy(*C);
@@ -502,6 +511,10 @@
 IRBuilder<> IRBCtor(Ctor->getEntryBlock().getTerminator());
 IRBCtor.CreateCall(InitFunction, {SecStartEnd.first, SecStartEnd.second});
   }
+
+  if (Options.CollectControlFlow)
+CreateSecStartEnd(M, SanCovCFsSectionName, IntptrPtrTy);
+
   appendToUsed(M, GlobalsToAppendToUsed);
   appendToCompilerUsed(M, GlobalsToAppendToCompilerUsed);
   return true;
@@ -671,6 +684,9 @@
 }
   }
 
+  if (Options.CollectControlFlow)
+CollectFunctionC

[PATCH] D133157: Add -fsanitizer-coverage=control-flow

2022-09-06 Thread Navid Emamdoost via Phabricator via cfe-commits
Navidem updated this revision to Diff 458321.
Navidem added a comment.

Apply comments.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D133157/new/

https://reviews.llvm.org/D133157

Files:
  clang/docs/SanitizerCoverage.rst
  clang/include/clang/Basic/CodeGenOptions.def
  clang/include/clang/Basic/CodeGenOptions.h
  clang/include/clang/Driver/Options.td
  clang/lib/CodeGen/BackendUtil.cpp
  clang/lib/Driver/SanitizerArgs.cpp
  llvm/include/llvm/Transforms/Instrumentation.h
  llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp
  llvm/test/Instrumentation/SanitizerCoverage/control-flow.ll

Index: llvm/test/Instrumentation/SanitizerCoverage/control-flow.ll
===
--- /dev/null
+++ llvm/test/Instrumentation/SanitizerCoverage/control-flow.ll
@@ -0,0 +1,22 @@
+; Test -sanitizer-coverage-control-flow.
+; RUN: opt < %s -passes='module(sancov-module)' -sanitizer-coverage-level=3 -sanitizer-coverage-control-flow -S | FileCheck %s
+
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-unknown-linux-gnu"
+define void @foo(ptr %a) sanitize_address {
+entry:
+  %tobool = icmp eq i32* %a, null
+  br i1 %tobool, label %if.end, label %if.then
+
+  if.then:  ; preds = %entry
+  store i32 0, i32* %a, align 4
+  call void @foo(i32* %a)
+  br label %if.end
+
+  if.end:   ; preds = %entry, %if.then
+  ret void
+}
+
+; CHECK: private constant [17 x i64*] [{{.*}}@foo{{.*}}blockaddress{{.*}}blockaddress{{.*}}blockaddress{{.*}}blockaddress{{.*}}blockaddress{{.*}}blockaddress{{.*}}blockaddress{{.*}}@foo{{.*}}null{{.*}}null], section "__sancov_cfs", comdat($foo), align 8
+; CHECK:  @__start___sancov_cfs = extern_weak hidden global i64*
+; CHECK-NEXT: @__stop___sancov_cfs = extern_weak hidden global i64*
Index: llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp
===
--- llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp
+++ llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp
@@ -80,6 +80,7 @@
 const char SanCovCountersSectionName[] = "sancov_cntrs";
 const char SanCovBoolFlagSectionName[] = "sancov_bools";
 const char SanCovPCsSectionName[] = "sancov_pcs";
+const char SanCovCFsSectionName[] = "sancov_cfs";
 
 const char SanCovLowestStackName[] = "__sancov_lowest_stack";
 
@@ -147,6 +148,10 @@
   cl::desc("max stack depth tracing"),
   cl::Hidden, cl::init(false));
 
+static cl::opt ClCollectCF("sanitizer-coverage-control-flow",
+  cl::desc("collect control flow for each function"),
+  cl::Hidden, cl::init(false));
+
 namespace {
 
 SanitizerCoverageOptions getOptions(int LegacyCoverageLevel) {
@@ -193,6 +198,7 @@
   !Options.Inline8bitCounters && !Options.StackDepth &&
   !Options.InlineBoolFlag && !Options.TraceLoads && !Options.TraceStores)
 Options.TracePCGuard = true; // TracePCGuard is default.
+  Options.CollectControlFlow |= ClCollectCF;
   return Options;
 }
 
@@ -212,6 +218,7 @@
 PostDomTreeCallback PDTCallback);
 
 private:
+  void createFunctionControlFlow(Function &F);
   void instrumentFunction(Function &F, DomTreeCallback DTCallback,
   PostDomTreeCallback PDTCallback);
   void InjectCoverageForIndirectCalls(Function &F,
@@ -270,6 +277,7 @@
   GlobalVariable *Function8bitCounterArray;  // for inline-8bit-counters.
   GlobalVariable *FunctionBoolArray; // for inline-bool-flag.
   GlobalVariable *FunctionPCsArray;  // for pc-table.
+  GlobalVariable *FunctionCFsArray;  // for control flow table
   SmallVector GlobalsToAppendToUsed;
   SmallVector GlobalsToAppendToCompilerUsed;
 
@@ -378,6 +386,7 @@
   Function8bitCounterArray = nullptr;
   FunctionBoolArray = nullptr;
   FunctionPCsArray = nullptr;
+  FunctionCFsArray = nullptr;
   IntptrTy = Type::getIntNTy(*C, DL->getPointerSizeInBits());
   IntptrPtrTy = PointerType::getUnqual(IntptrTy);
   Type *VoidTy = Type::getVoidTy(*C);
@@ -502,6 +511,10 @@
 IRBuilder<> IRBCtor(Ctor->getEntryBlock().getTerminator());
 IRBCtor.CreateCall(InitFunction, {SecStartEnd.first, SecStartEnd.second});
   }
+
+  if (Options.CollectControlFlow)
+CreateSecStartEnd(M, SanCovCFsSectionName, IntptrPtrTy);
+
   appendToUsed(M, GlobalsToAppendToUsed);
   appendToCompilerUsed(M, GlobalsToAppendToCompilerUsed);
   return true;
@@ -671,6 +684,9 @@
 }
   }
 
+  if (Options.CollectControlFlow)
+createFunctionControlFlow(F);
+
   InjectCoverage(F, BlocksToInstrument, IsLeafFunc);
   InjectCoverageForIndirectCalls(F, IndirCalls);
   InjectTraceForCmp(F, CmpTraceTargets);
@@ -1028,3 +

[PATCH] D133157: Add -fsanitizer-coverage=control-flow

2022-09-08 Thread Navid Emamdoost via Phabricator via cfe-commits
Navidem updated this revision to Diff 458958.
Navidem added a comment.

Add __sanitizer_cov_cfs_init


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D133157/new/

https://reviews.llvm.org/D133157

Files:
  clang/docs/SanitizerCoverage.rst
  clang/include/clang/Basic/CodeGenOptions.def
  clang/include/clang/Basic/CodeGenOptions.h
  clang/include/clang/Driver/Options.td
  clang/lib/CodeGen/BackendUtil.cpp
  clang/lib/Driver/SanitizerArgs.cpp
  llvm/include/llvm/Transforms/Instrumentation.h
  llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp
  llvm/test/Instrumentation/SanitizerCoverage/control-flow.ll

Index: llvm/test/Instrumentation/SanitizerCoverage/control-flow.ll
===
--- /dev/null
+++ llvm/test/Instrumentation/SanitizerCoverage/control-flow.ll
@@ -0,0 +1,22 @@
+; Test -sanitizer-coverage-control-flow.
+; RUN: opt < %s -passes='module(sancov-module)' -sanitizer-coverage-level=3 -sanitizer-coverage-control-flow -S | FileCheck %s
+
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-unknown-linux-gnu"
+define void @foo(ptr %a) sanitize_address {
+entry:
+  %tobool = icmp eq i32* %a, null
+  br i1 %tobool, label %if.end, label %if.then
+
+  if.then:  ; preds = %entry
+  store i32 0, i32* %a, align 4
+  call void @foo(i32* %a)
+  br label %if.end
+
+  if.end:   ; preds = %entry, %if.then
+  ret void
+}
+
+; CHECK: private constant [17 x ptr] [{{.*}}@foo{{.*}}blockaddress{{.*}}blockaddress{{.*}}blockaddress{{.*}}blockaddress{{.*}}blockaddress{{.*}}blockaddress{{.*}}blockaddress{{.*}}@foo{{.*}}null{{.*}}null], section "__sancov_cfs", comdat($foo), align 8
+; CHECK:  @__start___sancov_cfs = extern_weak hidden global
+; CHECK-NEXT: @__stop___sancov_cfs = extern_weak hidden global
Index: llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp
===
--- llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp
+++ llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp
@@ -75,11 +75,13 @@
 const char SanCov8bitCountersInitName[] = "__sanitizer_cov_8bit_counters_init";
 const char SanCovBoolFlagInitName[] = "__sanitizer_cov_bool_flag_init";
 const char SanCovPCsInitName[] = "__sanitizer_cov_pcs_init";
+const char SanCovCFsInitName[] = "__sanitizer_cov_cfs_init";
 
 const char SanCovGuardsSectionName[] = "sancov_guards";
 const char SanCovCountersSectionName[] = "sancov_cntrs";
 const char SanCovBoolFlagSectionName[] = "sancov_bools";
 const char SanCovPCsSectionName[] = "sancov_pcs";
+const char SanCovCFsSectionName[] = "sancov_cfs";
 
 const char SanCovLowestStackName[] = "__sancov_lowest_stack";
 
@@ -147,6 +149,10 @@
   cl::desc("max stack depth tracing"),
   cl::Hidden, cl::init(false));
 
+static cl::opt ClCollectCF("sanitizer-coverage-control-flow",
+  cl::desc("collect control flow for each function"),
+  cl::Hidden, cl::init(false));
+
 namespace {
 
 SanitizerCoverageOptions getOptions(int LegacyCoverageLevel) {
@@ -193,6 +199,7 @@
   !Options.Inline8bitCounters && !Options.StackDepth &&
   !Options.InlineBoolFlag && !Options.TraceLoads && !Options.TraceStores)
 Options.TracePCGuard = true; // TracePCGuard is default.
+  Options.CollectControlFlow |= ClCollectCF;
   return Options;
 }
 
@@ -212,6 +219,7 @@
 PostDomTreeCallback PDTCallback);
 
 private:
+  void createFunctionControlFlow(Function &F);
   void instrumentFunction(Function &F, DomTreeCallback DTCallback,
   PostDomTreeCallback PDTCallback);
   void InjectCoverageForIndirectCalls(Function &F,
@@ -270,6 +278,7 @@
   GlobalVariable *Function8bitCounterArray;  // for inline-8bit-counters.
   GlobalVariable *FunctionBoolArray; // for inline-bool-flag.
   GlobalVariable *FunctionPCsArray;  // for pc-table.
+  GlobalVariable *FunctionCFsArray;  // for control flow table
   SmallVector GlobalsToAppendToUsed;
   SmallVector GlobalsToAppendToCompilerUsed;
 
@@ -378,6 +387,7 @@
   Function8bitCounterArray = nullptr;
   FunctionBoolArray = nullptr;
   FunctionPCsArray = nullptr;
+  FunctionCFsArray = nullptr;
   IntptrTy = Type::getIntNTy(*C, DL->getPointerSizeInBits());
   IntptrPtrTy = PointerType::getUnqual(IntptrTy);
   Type *VoidTy = Type::getVoidTy(*C);
@@ -502,6 +512,15 @@
 IRBuilder<> IRBCtor(Ctor->getEntryBlock().getTerminator());
 IRBCtor.CreateCall(InitFunction, {SecStartEnd.first, SecStartEnd.second});
   }
+
+  if (Ctor && Options.CollectControlFlow) {
+auto SecStartEnd = CreateSecStartEnd(M, SanCovCFsSectionName, IntptrPtrTy);
+FunctionC

[PATCH] D133157: Add -fsanitizer-coverage=control-flow

2022-09-09 Thread Navid Emamdoost via Phabricator via cfe-commits
Navidem updated this revision to Diff 459157.
Navidem added a comment.

Update doc


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D133157/new/

https://reviews.llvm.org/D133157

Files:
  clang/docs/SanitizerCoverage.rst
  clang/include/clang/Basic/CodeGenOptions.def
  clang/include/clang/Basic/CodeGenOptions.h
  clang/include/clang/Driver/Options.td
  clang/lib/CodeGen/BackendUtil.cpp
  clang/lib/Driver/SanitizerArgs.cpp
  llvm/include/llvm/Transforms/Instrumentation.h
  llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp
  llvm/test/Instrumentation/SanitizerCoverage/control-flow.ll

Index: llvm/test/Instrumentation/SanitizerCoverage/control-flow.ll
===
--- /dev/null
+++ llvm/test/Instrumentation/SanitizerCoverage/control-flow.ll
@@ -0,0 +1,22 @@
+; Test -sanitizer-coverage-control-flow.
+; RUN: opt < %s -passes='module(sancov-module)' -sanitizer-coverage-level=3 -sanitizer-coverage-control-flow -S | FileCheck %s
+
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-unknown-linux-gnu"
+define void @foo(ptr %a) sanitize_address {
+entry:
+  %tobool = icmp eq i32* %a, null
+  br i1 %tobool, label %if.end, label %if.then
+
+  if.then:  ; preds = %entry
+  store i32 0, i32* %a, align 4
+  call void @foo(i32* %a)
+  br label %if.end
+
+  if.end:   ; preds = %entry, %if.then
+  ret void
+}
+
+; CHECK: private constant [17 x ptr] [{{.*}}@foo{{.*}}blockaddress{{.*}}blockaddress{{.*}}blockaddress{{.*}}blockaddress{{.*}}blockaddress{{.*}}blockaddress{{.*}}blockaddress{{.*}}@foo{{.*}}null{{.*}}null], section "__sancov_cfs", comdat($foo), align 8
+; CHECK:  @__start___sancov_cfs = extern_weak hidden global
+; CHECK-NEXT: @__stop___sancov_cfs = extern_weak hidden global
Index: llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp
===
--- llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp
+++ llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp
@@ -75,11 +75,13 @@
 const char SanCov8bitCountersInitName[] = "__sanitizer_cov_8bit_counters_init";
 const char SanCovBoolFlagInitName[] = "__sanitizer_cov_bool_flag_init";
 const char SanCovPCsInitName[] = "__sanitizer_cov_pcs_init";
+const char SanCovCFsInitName[] = "__sanitizer_cov_cfs_init";
 
 const char SanCovGuardsSectionName[] = "sancov_guards";
 const char SanCovCountersSectionName[] = "sancov_cntrs";
 const char SanCovBoolFlagSectionName[] = "sancov_bools";
 const char SanCovPCsSectionName[] = "sancov_pcs";
+const char SanCovCFsSectionName[] = "sancov_cfs";
 
 const char SanCovLowestStackName[] = "__sancov_lowest_stack";
 
@@ -147,6 +149,10 @@
   cl::desc("max stack depth tracing"),
   cl::Hidden, cl::init(false));
 
+static cl::opt ClCollectCF("sanitizer-coverage-control-flow",
+  cl::desc("collect control flow for each function"),
+  cl::Hidden, cl::init(false));
+
 namespace {
 
 SanitizerCoverageOptions getOptions(int LegacyCoverageLevel) {
@@ -193,6 +199,7 @@
   !Options.Inline8bitCounters && !Options.StackDepth &&
   !Options.InlineBoolFlag && !Options.TraceLoads && !Options.TraceStores)
 Options.TracePCGuard = true; // TracePCGuard is default.
+  Options.CollectControlFlow |= ClCollectCF;
   return Options;
 }
 
@@ -212,6 +219,7 @@
 PostDomTreeCallback PDTCallback);
 
 private:
+  void createFunctionControlFlow(Function &F);
   void instrumentFunction(Function &F, DomTreeCallback DTCallback,
   PostDomTreeCallback PDTCallback);
   void InjectCoverageForIndirectCalls(Function &F,
@@ -270,6 +278,7 @@
   GlobalVariable *Function8bitCounterArray;  // for inline-8bit-counters.
   GlobalVariable *FunctionBoolArray; // for inline-bool-flag.
   GlobalVariable *FunctionPCsArray;  // for pc-table.
+  GlobalVariable *FunctionCFsArray;  // for control flow table
   SmallVector GlobalsToAppendToUsed;
   SmallVector GlobalsToAppendToCompilerUsed;
 
@@ -378,6 +387,7 @@
   Function8bitCounterArray = nullptr;
   FunctionBoolArray = nullptr;
   FunctionPCsArray = nullptr;
+  FunctionCFsArray = nullptr;
   IntptrTy = Type::getIntNTy(*C, DL->getPointerSizeInBits());
   IntptrPtrTy = PointerType::getUnqual(IntptrTy);
   Type *VoidTy = Type::getVoidTy(*C);
@@ -502,6 +512,15 @@
 IRBuilder<> IRBCtor(Ctor->getEntryBlock().getTerminator());
 IRBCtor.CreateCall(InitFunction, {SecStartEnd.first, SecStartEnd.second});
   }
+
+  if (Ctor && Options.CollectControlFlow) {
+auto SecStartEnd = CreateSecStartEnd(M, SanCovCFsSectionName, IntptrPtrTy);
+FunctionCallee InitFunction

[PATCH] D133157: Add -fsanitizer-coverage=control-flow

2022-09-09 Thread Navid Emamdoost via Phabricator via cfe-commits
Navidem marked an inline comment as done and an inline comment as not done.
Navidem added inline comments.



Comment at: clang/lib/Driver/SanitizerArgs.cpp:807
 << "-fsanitize-coverage=[func|bb|edge]"
-<< "-fsanitize-coverage=[func|bb|edge],[trace-pc-guard|trace-pc]";
+<< 
"-fsanitize-coverage=[func|bb|edge],[trace-pc-guard|trace-pc|control-flow]";
   }

vitalybuka wrote:
> shouldn't this be:
> ,[trace-pc-guard|trace-pc],[control-flow]
> 
> probably even:
> [,(trace-pc-guard|trace-pc)][,control-flow]
> shouldn't this be:
> ,[trace-pc-guard|trace-pc],[control-flow]
> 
> probably even:
> [,(trace-pc-guard|trace-pc)][,control-flow]




Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D133157/new/

https://reviews.llvm.org/D133157

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D133157: Add -fsanitizer-coverage=control-flow

2022-09-09 Thread Navid Emamdoost via Phabricator via cfe-commits
Navidem updated this revision to Diff 459201.
Navidem added a comment.

Bring back the runtime test.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D133157/new/

https://reviews.llvm.org/D133157

Files:
  clang/docs/SanitizerCoverage.rst
  clang/include/clang/Basic/CodeGenOptions.def
  clang/include/clang/Basic/CodeGenOptions.h
  clang/include/clang/Driver/Options.td
  clang/lib/CodeGen/BackendUtil.cpp
  clang/lib/Driver/SanitizerArgs.cpp
  
compiler-rt/test/sanitizer_common/TestCases/sanitizer_coverage_control_flow.cpp
  llvm/include/llvm/Transforms/Instrumentation.h
  llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp
  llvm/test/Instrumentation/SanitizerCoverage/control-flow.ll

Index: llvm/test/Instrumentation/SanitizerCoverage/control-flow.ll
===
--- /dev/null
+++ llvm/test/Instrumentation/SanitizerCoverage/control-flow.ll
@@ -0,0 +1,22 @@
+; Test -sanitizer-coverage-control-flow.
+; RUN: opt < %s -passes='module(sancov-module)' -sanitizer-coverage-level=3 -sanitizer-coverage-control-flow -S | FileCheck %s
+
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-unknown-linux-gnu"
+define void @foo(ptr %a) sanitize_address {
+entry:
+  %tobool = icmp eq i32* %a, null
+  br i1 %tobool, label %if.end, label %if.then
+
+  if.then:  ; preds = %entry
+  store i32 0, i32* %a, align 4
+  call void @foo(i32* %a)
+  br label %if.end
+
+  if.end:   ; preds = %entry, %if.then
+  ret void
+}
+
+; CHECK: private constant [17 x ptr] [{{.*}}@foo{{.*}}blockaddress{{.*}}blockaddress{{.*}}blockaddress{{.*}}blockaddress{{.*}}blockaddress{{.*}}blockaddress{{.*}}blockaddress{{.*}}@foo{{.*}}null{{.*}}null], section "__sancov_cfs", comdat($foo), align 8
+; CHECK:  @__start___sancov_cfs = extern_weak hidden global
+; CHECK-NEXT: @__stop___sancov_cfs = extern_weak hidden global
Index: llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp
===
--- llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp
+++ llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp
@@ -75,11 +75,13 @@
 const char SanCov8bitCountersInitName[] = "__sanitizer_cov_8bit_counters_init";
 const char SanCovBoolFlagInitName[] = "__sanitizer_cov_bool_flag_init";
 const char SanCovPCsInitName[] = "__sanitizer_cov_pcs_init";
+const char SanCovCFsInitName[] = "__sanitizer_cov_cfs_init";
 
 const char SanCovGuardsSectionName[] = "sancov_guards";
 const char SanCovCountersSectionName[] = "sancov_cntrs";
 const char SanCovBoolFlagSectionName[] = "sancov_bools";
 const char SanCovPCsSectionName[] = "sancov_pcs";
+const char SanCovCFsSectionName[] = "sancov_cfs";
 
 const char SanCovLowestStackName[] = "__sancov_lowest_stack";
 
@@ -147,6 +149,10 @@
   cl::desc("max stack depth tracing"),
   cl::Hidden, cl::init(false));
 
+static cl::opt ClCollectCF("sanitizer-coverage-control-flow",
+  cl::desc("collect control flow for each function"),
+  cl::Hidden, cl::init(false));
+
 namespace {
 
 SanitizerCoverageOptions getOptions(int LegacyCoverageLevel) {
@@ -193,6 +199,7 @@
   !Options.Inline8bitCounters && !Options.StackDepth &&
   !Options.InlineBoolFlag && !Options.TraceLoads && !Options.TraceStores)
 Options.TracePCGuard = true; // TracePCGuard is default.
+  Options.CollectControlFlow |= ClCollectCF;
   return Options;
 }
 
@@ -212,6 +219,7 @@
 PostDomTreeCallback PDTCallback);
 
 private:
+  void createFunctionControlFlow(Function &F);
   void instrumentFunction(Function &F, DomTreeCallback DTCallback,
   PostDomTreeCallback PDTCallback);
   void InjectCoverageForIndirectCalls(Function &F,
@@ -270,6 +278,7 @@
   GlobalVariable *Function8bitCounterArray;  // for inline-8bit-counters.
   GlobalVariable *FunctionBoolArray; // for inline-bool-flag.
   GlobalVariable *FunctionPCsArray;  // for pc-table.
+  GlobalVariable *FunctionCFsArray;  // for control flow table
   SmallVector GlobalsToAppendToUsed;
   SmallVector GlobalsToAppendToCompilerUsed;
 
@@ -378,6 +387,7 @@
   Function8bitCounterArray = nullptr;
   FunctionBoolArray = nullptr;
   FunctionPCsArray = nullptr;
+  FunctionCFsArray = nullptr;
   IntptrTy = Type::getIntNTy(*C, DL->getPointerSizeInBits());
   IntptrPtrTy = PointerType::getUnqual(IntptrTy);
   Type *VoidTy = Type::getVoidTy(*C);
@@ -502,6 +512,15 @@
 IRBuilder<> IRBCtor(Ctor->getEntryBlock().getTerminator());
 IRBCtor.CreateCall(InitFunction, {SecStartEnd.first, SecStartEnd.second});
   }
+
+  if (Ctor && Options.CollectControlFlow) {
+auto Se

[PATCH] D133157: Add -fsanitizer-coverage=control-flow

2022-09-09 Thread Navid Emamdoost via Phabricator via cfe-commits
Navidem added inline comments.



Comment at: clang/lib/Driver/SanitizerArgs.cpp:814
 (CoverageTracePC | CoverageTracePCGuard | CoverageInline8bitCounters |
- CoverageInlineBoolFlag))
+ CoverageInlineBoolFlag | CoverageControlFlow))
   CoverageFeatures |= CoverageEdge;

vitalybuka wrote:
> why do you need CoverageEdge if enabled CoverageControlFlow?
No essential need, but here I am implicitly enabling `edge` when 
instrumentation type is not specified. This was the way that I could get 
`-fsanitizer-coverage=control-flow` working without passing 
`-fsanitizer-coverage=bb,control-flow`.



Comment at: clang/lib/Driver/SanitizerArgs.cpp:807
 << "-fsanitize-coverage=[func|bb|edge]"
-<< "-fsanitize-coverage=[func|bb|edge],[trace-pc-guard|trace-pc]";
+<< 
"-fsanitize-coverage=[func|bb|edge],[trace-pc-guard|trace-pc|control-flow]";
   }

Navidem wrote:
> vitalybuka wrote:
> > shouldn't this be:
> > ,[trace-pc-guard|trace-pc],[control-flow]
> > 
> > probably even:
> > [,(trace-pc-guard|trace-pc)][,control-flow]
> > shouldn't this be:
> > ,[trace-pc-guard|trace-pc],[control-flow]
> > 
> > probably even:
> > [,(trace-pc-guard|trace-pc)][,control-flow]
> 
> 
> shouldn't this be:
> ,[trace-pc-guard|trace-pc],[control-flow]

This makes sense, thanks!




Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D133157/new/

https://reviews.llvm.org/D133157

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D133157: Add -fsanitizer-coverage=control-flow

2022-09-14 Thread Navid Emamdoost via Phabricator via cfe-commits
Navidem updated this revision to Diff 460215.
Navidem added a comment.

Update the rt test


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D133157/new/

https://reviews.llvm.org/D133157

Files:
  clang/docs/SanitizerCoverage.rst
  clang/include/clang/Basic/CodeGenOptions.def
  clang/include/clang/Basic/CodeGenOptions.h
  clang/include/clang/Driver/Options.td
  clang/lib/CodeGen/BackendUtil.cpp
  clang/lib/Driver/SanitizerArgs.cpp
  
compiler-rt/test/sanitizer_common/TestCases/sanitizer_coverage_control_flow.cpp
  llvm/include/llvm/Transforms/Instrumentation.h
  llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp
  llvm/test/Instrumentation/SanitizerCoverage/control-flow.ll

Index: llvm/test/Instrumentation/SanitizerCoverage/control-flow.ll
===
--- /dev/null
+++ llvm/test/Instrumentation/SanitizerCoverage/control-flow.ll
@@ -0,0 +1,22 @@
+; Test -sanitizer-coverage-control-flow.
+; RUN: opt < %s -passes='module(sancov-module)' -sanitizer-coverage-level=3 -sanitizer-coverage-control-flow -S | FileCheck %s
+
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-unknown-linux-gnu"
+define void @foo(ptr %a) sanitize_address {
+entry:
+  %tobool = icmp eq i32* %a, null
+  br i1 %tobool, label %if.end, label %if.then
+
+  if.then:  ; preds = %entry
+  store i32 0, i32* %a, align 4
+  call void @foo(i32* %a)
+  br label %if.end
+
+  if.end:   ; preds = %entry, %if.then
+  ret void
+}
+
+; CHECK: private constant [17 x ptr] [{{.*}}@foo{{.*}}blockaddress{{.*}}blockaddress{{.*}}blockaddress{{.*}}blockaddress{{.*}}blockaddress{{.*}}blockaddress{{.*}}blockaddress{{.*}}@foo{{.*}}null{{.*}}null], section "__sancov_cfs", comdat($foo), align 8
+; CHECK:  @__start___sancov_cfs = extern_weak hidden global
+; CHECK-NEXT: @__stop___sancov_cfs = extern_weak hidden global
Index: llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp
===
--- llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp
+++ llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp
@@ -75,11 +75,13 @@
 const char SanCov8bitCountersInitName[] = "__sanitizer_cov_8bit_counters_init";
 const char SanCovBoolFlagInitName[] = "__sanitizer_cov_bool_flag_init";
 const char SanCovPCsInitName[] = "__sanitizer_cov_pcs_init";
+const char SanCovCFsInitName[] = "__sanitizer_cov_cfs_init";
 
 const char SanCovGuardsSectionName[] = "sancov_guards";
 const char SanCovCountersSectionName[] = "sancov_cntrs";
 const char SanCovBoolFlagSectionName[] = "sancov_bools";
 const char SanCovPCsSectionName[] = "sancov_pcs";
+const char SanCovCFsSectionName[] = "sancov_cfs";
 
 const char SanCovLowestStackName[] = "__sancov_lowest_stack";
 
@@ -147,6 +149,10 @@
   cl::desc("max stack depth tracing"),
   cl::Hidden, cl::init(false));
 
+static cl::opt ClCollectCF("sanitizer-coverage-control-flow",
+  cl::desc("collect control flow for each function"),
+  cl::Hidden, cl::init(false));
+
 namespace {
 
 SanitizerCoverageOptions getOptions(int LegacyCoverageLevel) {
@@ -193,6 +199,7 @@
   !Options.Inline8bitCounters && !Options.StackDepth &&
   !Options.InlineBoolFlag && !Options.TraceLoads && !Options.TraceStores)
 Options.TracePCGuard = true; // TracePCGuard is default.
+  Options.CollectControlFlow |= ClCollectCF;
   return Options;
 }
 
@@ -212,6 +219,7 @@
 PostDomTreeCallback PDTCallback);
 
 private:
+  void createFunctionControlFlow(Function &F);
   void instrumentFunction(Function &F, DomTreeCallback DTCallback,
   PostDomTreeCallback PDTCallback);
   void InjectCoverageForIndirectCalls(Function &F,
@@ -270,6 +278,7 @@
   GlobalVariable *Function8bitCounterArray;  // for inline-8bit-counters.
   GlobalVariable *FunctionBoolArray; // for inline-bool-flag.
   GlobalVariable *FunctionPCsArray;  // for pc-table.
+  GlobalVariable *FunctionCFsArray;  // for control flow table
   SmallVector GlobalsToAppendToUsed;
   SmallVector GlobalsToAppendToCompilerUsed;
 
@@ -378,6 +387,7 @@
   Function8bitCounterArray = nullptr;
   FunctionBoolArray = nullptr;
   FunctionPCsArray = nullptr;
+  FunctionCFsArray = nullptr;
   IntptrTy = Type::getIntNTy(*C, DL->getPointerSizeInBits());
   IntptrPtrTy = PointerType::getUnqual(IntptrTy);
   Type *VoidTy = Type::getVoidTy(*C);
@@ -502,6 +512,15 @@
 IRBuilder<> IRBCtor(Ctor->getEntryBlock().getTerminator());
 IRBCtor.CreateCall(InitFunction, {SecStartEnd.first, SecStartEnd.second});
   }
+
+  if (Ctor && Options.CollectControlFlow) {
+auto SecStartEnd 

[PATCH] D133157: Add -fsanitizer-coverage=control-flow

2022-09-14 Thread Navid Emamdoost via Phabricator via cfe-commits
Navidem updated this revision to Diff 460232.
Navidem added a comment.

Enhance rt test.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D133157/new/

https://reviews.llvm.org/D133157

Files:
  clang/docs/SanitizerCoverage.rst
  clang/include/clang/Basic/CodeGenOptions.def
  clang/include/clang/Basic/CodeGenOptions.h
  clang/include/clang/Driver/Options.td
  clang/lib/CodeGen/BackendUtil.cpp
  clang/lib/Driver/SanitizerArgs.cpp
  
compiler-rt/test/sanitizer_common/TestCases/sanitizer_coverage_control_flow.cpp
  llvm/include/llvm/Transforms/Instrumentation.h
  llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp
  llvm/test/Instrumentation/SanitizerCoverage/control-flow.ll

Index: llvm/test/Instrumentation/SanitizerCoverage/control-flow.ll
===
--- /dev/null
+++ llvm/test/Instrumentation/SanitizerCoverage/control-flow.ll
@@ -0,0 +1,22 @@
+; Test -sanitizer-coverage-control-flow.
+; RUN: opt < %s -passes='module(sancov-module)' -sanitizer-coverage-level=3 -sanitizer-coverage-control-flow -S | FileCheck %s
+
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-unknown-linux-gnu"
+define void @foo(ptr %a) sanitize_address {
+entry:
+  %tobool = icmp eq i32* %a, null
+  br i1 %tobool, label %if.end, label %if.then
+
+  if.then:  ; preds = %entry
+  store i32 0, i32* %a, align 4
+  call void @foo(i32* %a)
+  br label %if.end
+
+  if.end:   ; preds = %entry, %if.then
+  ret void
+}
+
+; CHECK: private constant [17 x ptr] [{{.*}}@foo{{.*}}blockaddress{{.*}}blockaddress{{.*}}blockaddress{{.*}}blockaddress{{.*}}blockaddress{{.*}}blockaddress{{.*}}blockaddress{{.*}}@foo{{.*}}null{{.*}}null], section "__sancov_cfs", comdat($foo), align 8
+; CHECK:  @__start___sancov_cfs = extern_weak hidden global
+; CHECK-NEXT: @__stop___sancov_cfs = extern_weak hidden global
Index: llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp
===
--- llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp
+++ llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp
@@ -75,11 +75,13 @@
 const char SanCov8bitCountersInitName[] = "__sanitizer_cov_8bit_counters_init";
 const char SanCovBoolFlagInitName[] = "__sanitizer_cov_bool_flag_init";
 const char SanCovPCsInitName[] = "__sanitizer_cov_pcs_init";
+const char SanCovCFsInitName[] = "__sanitizer_cov_cfs_init";
 
 const char SanCovGuardsSectionName[] = "sancov_guards";
 const char SanCovCountersSectionName[] = "sancov_cntrs";
 const char SanCovBoolFlagSectionName[] = "sancov_bools";
 const char SanCovPCsSectionName[] = "sancov_pcs";
+const char SanCovCFsSectionName[] = "sancov_cfs";
 
 const char SanCovLowestStackName[] = "__sancov_lowest_stack";
 
@@ -147,6 +149,10 @@
   cl::desc("max stack depth tracing"),
   cl::Hidden, cl::init(false));
 
+static cl::opt ClCollectCF("sanitizer-coverage-control-flow",
+  cl::desc("collect control flow for each function"),
+  cl::Hidden, cl::init(false));
+
 namespace {
 
 SanitizerCoverageOptions getOptions(int LegacyCoverageLevel) {
@@ -193,6 +199,7 @@
   !Options.Inline8bitCounters && !Options.StackDepth &&
   !Options.InlineBoolFlag && !Options.TraceLoads && !Options.TraceStores)
 Options.TracePCGuard = true; // TracePCGuard is default.
+  Options.CollectControlFlow |= ClCollectCF;
   return Options;
 }
 
@@ -212,6 +219,7 @@
 PostDomTreeCallback PDTCallback);
 
 private:
+  void createFunctionControlFlow(Function &F);
   void instrumentFunction(Function &F, DomTreeCallback DTCallback,
   PostDomTreeCallback PDTCallback);
   void InjectCoverageForIndirectCalls(Function &F,
@@ -270,6 +278,7 @@
   GlobalVariable *Function8bitCounterArray;  // for inline-8bit-counters.
   GlobalVariable *FunctionBoolArray; // for inline-bool-flag.
   GlobalVariable *FunctionPCsArray;  // for pc-table.
+  GlobalVariable *FunctionCFsArray;  // for control flow table
   SmallVector GlobalsToAppendToUsed;
   SmallVector GlobalsToAppendToCompilerUsed;
 
@@ -378,6 +387,7 @@
   Function8bitCounterArray = nullptr;
   FunctionBoolArray = nullptr;
   FunctionPCsArray = nullptr;
+  FunctionCFsArray = nullptr;
   IntptrTy = Type::getIntNTy(*C, DL->getPointerSizeInBits());
   IntptrPtrTy = PointerType::getUnqual(IntptrTy);
   Type *VoidTy = Type::getVoidTy(*C);
@@ -502,6 +512,15 @@
 IRBuilder<> IRBCtor(Ctor->getEntryBlock().getTerminator());
 IRBCtor.CreateCall(InitFunction, {SecStartEnd.first, SecStartEnd.second});
   }
+
+  if (Ctor && Options.CollectControlFlow) {
+auto SecStartEnd = 

[PATCH] D133157: Add -fsanitizer-coverage=control-flow

2022-09-14 Thread Navid Emamdoost via Phabricator via cfe-commits
Navidem marked an inline comment as done.
Navidem added inline comments.



Comment at: 
compiler-rt/test/sanitizer_common/TestCases/sanitizer_coverage_control_flow.cpp:15
+extern "C" void __sanitizer_cov_cfs_init(const uintptr_t *cfs_beg,
+ const uintptr_t *cfs_end) {
+  CFS_BEG = (uintptr_t *)cfs_beg;

vitalybuka wrote:
> vitalybuka wrote:
> > would you like to add some printing function as for other coverage types?
> actually printing can be don't in follow up patch, but it may simplify the 
> test, you will not need iterate it in the test.
> actually printing can be don't in follow up patch, but it may simplify the 
> test, you will not need iterate it in the test.

I'm not sure I follow what you are suggesting.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D133157/new/

https://reviews.llvm.org/D133157

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D133157: Add -fsanitizer-coverage=control-flow

2022-09-14 Thread Navid Emamdoost via Phabricator via cfe-commits
Navidem updated this revision to Diff 460251.
Navidem added a comment.

Use CHECK-DAG and separate function for checking.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D133157/new/

https://reviews.llvm.org/D133157

Files:
  clang/docs/SanitizerCoverage.rst
  clang/include/clang/Basic/CodeGenOptions.def
  clang/include/clang/Basic/CodeGenOptions.h
  clang/include/clang/Driver/Options.td
  clang/lib/CodeGen/BackendUtil.cpp
  clang/lib/Driver/SanitizerArgs.cpp
  
compiler-rt/test/sanitizer_common/TestCases/sanitizer_coverage_control_flow.cpp
  llvm/include/llvm/Transforms/Instrumentation.h
  llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp
  llvm/test/Instrumentation/SanitizerCoverage/control-flow.ll

Index: llvm/test/Instrumentation/SanitizerCoverage/control-flow.ll
===
--- /dev/null
+++ llvm/test/Instrumentation/SanitizerCoverage/control-flow.ll
@@ -0,0 +1,22 @@
+; Test -sanitizer-coverage-control-flow.
+; RUN: opt < %s -passes='module(sancov-module)' -sanitizer-coverage-level=3 -sanitizer-coverage-control-flow -S | FileCheck %s
+
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-unknown-linux-gnu"
+define void @foo(ptr %a) sanitize_address {
+entry:
+  %tobool = icmp eq i32* %a, null
+  br i1 %tobool, label %if.end, label %if.then
+
+  if.then:  ; preds = %entry
+  store i32 0, i32* %a, align 4
+  call void @foo(i32* %a)
+  br label %if.end
+
+  if.end:   ; preds = %entry, %if.then
+  ret void
+}
+
+; CHECK: private constant [17 x ptr] [{{.*}}@foo{{.*}}blockaddress{{.*}}blockaddress{{.*}}blockaddress{{.*}}blockaddress{{.*}}blockaddress{{.*}}blockaddress{{.*}}blockaddress{{.*}}@foo{{.*}}null{{.*}}null], section "__sancov_cfs", comdat($foo), align 8
+; CHECK:  @__start___sancov_cfs = extern_weak hidden global
+; CHECK-NEXT: @__stop___sancov_cfs = extern_weak hidden global
Index: llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp
===
--- llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp
+++ llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp
@@ -75,11 +75,13 @@
 const char SanCov8bitCountersInitName[] = "__sanitizer_cov_8bit_counters_init";
 const char SanCovBoolFlagInitName[] = "__sanitizer_cov_bool_flag_init";
 const char SanCovPCsInitName[] = "__sanitizer_cov_pcs_init";
+const char SanCovCFsInitName[] = "__sanitizer_cov_cfs_init";
 
 const char SanCovGuardsSectionName[] = "sancov_guards";
 const char SanCovCountersSectionName[] = "sancov_cntrs";
 const char SanCovBoolFlagSectionName[] = "sancov_bools";
 const char SanCovPCsSectionName[] = "sancov_pcs";
+const char SanCovCFsSectionName[] = "sancov_cfs";
 
 const char SanCovLowestStackName[] = "__sancov_lowest_stack";
 
@@ -147,6 +149,10 @@
   cl::desc("max stack depth tracing"),
   cl::Hidden, cl::init(false));
 
+static cl::opt ClCollectCF("sanitizer-coverage-control-flow",
+  cl::desc("collect control flow for each function"),
+  cl::Hidden, cl::init(false));
+
 namespace {
 
 SanitizerCoverageOptions getOptions(int LegacyCoverageLevel) {
@@ -193,6 +199,7 @@
   !Options.Inline8bitCounters && !Options.StackDepth &&
   !Options.InlineBoolFlag && !Options.TraceLoads && !Options.TraceStores)
 Options.TracePCGuard = true; // TracePCGuard is default.
+  Options.CollectControlFlow |= ClCollectCF;
   return Options;
 }
 
@@ -212,6 +219,7 @@
 PostDomTreeCallback PDTCallback);
 
 private:
+  void createFunctionControlFlow(Function &F);
   void instrumentFunction(Function &F, DomTreeCallback DTCallback,
   PostDomTreeCallback PDTCallback);
   void InjectCoverageForIndirectCalls(Function &F,
@@ -270,6 +278,7 @@
   GlobalVariable *Function8bitCounterArray;  // for inline-8bit-counters.
   GlobalVariable *FunctionBoolArray; // for inline-bool-flag.
   GlobalVariable *FunctionPCsArray;  // for pc-table.
+  GlobalVariable *FunctionCFsArray;  // for control flow table
   SmallVector GlobalsToAppendToUsed;
   SmallVector GlobalsToAppendToCompilerUsed;
 
@@ -378,6 +387,7 @@
   Function8bitCounterArray = nullptr;
   FunctionBoolArray = nullptr;
   FunctionPCsArray = nullptr;
+  FunctionCFsArray = nullptr;
   IntptrTy = Type::getIntNTy(*C, DL->getPointerSizeInBits());
   IntptrPtrTy = PointerType::getUnqual(IntptrTy);
   Type *VoidTy = Type::getVoidTy(*C);
@@ -502,6 +512,15 @@
 IRBuilder<> IRBCtor(Ctor->getEntryBlock().getTerminator());
 IRBCtor.CreateCall(InitFunction, {SecStartEnd.first, SecStartEnd.second});
   }
+
+  if (Ctor && Options.CollectContro

[PATCH] D133157: Add -fsanitizer-coverage=control-flow

2022-09-14 Thread Navid Emamdoost via Phabricator via cfe-commits
Navidem marked 3 inline comments as done.
Navidem added inline comments.



Comment at: 
compiler-rt/test/sanitizer_common/TestCases/sanitizer_coverage_control_flow.cpp:15
+extern "C" void __sanitizer_cov_cfs_init(const uintptr_t *cfs_beg,
+ const uintptr_t *cfs_end) {
+  CFS_BEG = (uintptr_t *)cfs_beg;

vitalybuka wrote:
> Navidem wrote:
> > vitalybuka wrote:
> > > vitalybuka wrote:
> > > > would you like to add some printing function as for other coverage 
> > > > types?
> > > actually printing can be don't in follow up patch, but it may simplify 
> > > the test, you will not need iterate it in the test.
> > > actually printing can be don't in follow up patch, but it may simplify 
> > > the test, you will not need iterate it in the test.
> > 
> > I'm not sure I follow what you are suggesting.
> Check this out D108405
> then you can hook your data into DumpCoverage() 
> then you can replace entire "while (pt < CFS_END) {" loop with set of CHECK:
> Check this out D108405
> then you can hook your data into DumpCoverage() 
> then you can replace entire "while (pt < CFS_END) {" loop with set of CHECK:

I see, thanks for the pointer. I think I leave it for later.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D133157/new/

https://reviews.llvm.org/D133157

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D133157: Add -fsanitizer-coverage=control-flow

2022-09-15 Thread Navid Emamdoost via Phabricator via cfe-commits
Navidem added a comment.

Thanks @kcc @vitalybuka, I do not have commit access.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D133157/new/

https://reviews.llvm.org/D133157

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits