[llvm] [ASan] Allow for passing AddressSanitizer command line options through the AddressSanitizerOptions struct. (PR #72439)

Usama Hameed via llvm-commits llvm-commits at lists.llvm.org
Thu Nov 16 16:30:46 PST 2023


https://github.com/usama54321 updated https://github.com/llvm/llvm-project/pull/72439

>From 977a72c453af9d4ebb1ace43daecadf7781d1a8d Mon Sep 17 00:00:00 2001
From: usama <u_hameed at apple.com>
Date: Wed, 15 Nov 2023 13:03:13 -0800
Subject: [PATCH] [ASan] Allow for passing AddressSanitizer command line
 options through the AddressSanitizerOptions struct.

This patch adds the ability to pass values for the command line options
of -max-inline-poisoning-size, -instrumentation-with-calls-threshold and
-asan-guard-against-version-mismatch through the AddressSanitizerOptions
struct. The motivation is to use these new options when using the pass
in Swift.

rdar://118470958
---
 .../Instrumentation/AddressSanitizer.h        |  8 +++
 .../Instrumentation/AddressSanitizer.cpp      | 71 +++++++++++--------
 2 files changed, 51 insertions(+), 28 deletions(-)

diff --git a/llvm/include/llvm/Transforms/Instrumentation/AddressSanitizer.h b/llvm/include/llvm/Transforms/Instrumentation/AddressSanitizer.h
index ca54387306664c9..188a4c386444090 100644
--- a/llvm/include/llvm/Transforms/Instrumentation/AddressSanitizer.h
+++ b/llvm/include/llvm/Transforms/Instrumentation/AddressSanitizer.h
@@ -20,12 +20,20 @@ namespace llvm {
 class Module;
 class raw_ostream;
 
+static const int InstrumentationWithCallsThreshold = 7000;
+static const uint32_t MaxInlinePoisoningSize = 64;
+static bool InsertVersionCheck = true;
+
 struct AddressSanitizerOptions {
   bool CompileKernel = false;
   bool Recover = false;
   bool UseAfterScope = false;
   AsanDetectStackUseAfterReturnMode UseAfterReturn =
       AsanDetectStackUseAfterReturnMode::Runtime;
+  int InstrumentationWithCallsThreshold =
+      llvm::InstrumentationWithCallsThreshold;
+  uint32_t MaxInlinePoisoningSize = llvm::MaxInlinePoisoningSize;
+  bool InsertVersionCheck = llvm::InsertVersionCheck;
 };
 
 /// Public interface to the address sanitizer module pass for instrumenting code
diff --git a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
index 80c044b6bee8da2..4b2cba205bf2275 100644
--- a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
@@ -201,8 +201,8 @@ static cl::opt<bool> ClRecover(
 
 static cl::opt<bool> ClInsertVersionCheck(
     "asan-guard-against-version-mismatch",
-    cl::desc("Guard against compiler/runtime version mismatch."),
-    cl::Hidden, cl::init(true));
+    cl::desc("Guard against compiler/runtime version mismatch."), cl::Hidden,
+    cl::init(InsertVersionCheck));
 
 // This flag may need to be replaced with -f[no-]asan-reads.
 static cl::opt<bool> ClInstrumentReads("asan-instrument-reads",
@@ -266,7 +266,7 @@ static cl::opt<uint32_t> ClMaxInlinePoisoningSize(
     "asan-max-inline-poisoning-size",
     cl::desc(
         "Inline shadow poisoning for blocks up to the given size in bytes."),
-    cl::Hidden, cl::init(64));
+    cl::Hidden, cl::init(MaxInlinePoisoningSize));
 
 static cl::opt<AsanDetectStackUseAfterReturnMode> ClUseAfterReturn(
     "asan-use-after-return",
@@ -323,11 +323,10 @@ static cl::opt<unsigned> ClRealignStack(
 
 static cl::opt<int> ClInstrumentationWithCallsThreshold(
     "asan-instrumentation-with-call-threshold",
-    cl::desc(
-        "If the function being instrumented contains more than "
-        "this number of memory accesses, use callbacks instead of "
-        "inline checks (-1 means never use callbacks)."),
-    cl::Hidden, cl::init(7000));
+    cl::desc("If the function being instrumented contains more than "
+             "this number of memory accesses, use callbacks instead of "
+             "inline checks (-1 means never use callbacks)."),
+    cl::Hidden, cl::init(InstrumentationWithCallsThreshold));
 
 static cl::opt<std::string> ClMemoryAccessCallbackPrefix(
     "asan-memory-access-callback-prefix",
@@ -644,18 +643,28 @@ namespace {
 
 /// AddressSanitizer: instrument the code in module to find memory bugs.
 struct AddressSanitizer {
-  AddressSanitizer(Module &M, const StackSafetyGlobalInfo *SSGI,
-                   bool CompileKernel = false, bool Recover = false,
-                   bool UseAfterScope = false,
-                   AsanDetectStackUseAfterReturnMode UseAfterReturn =
-                       AsanDetectStackUseAfterReturnMode::Runtime)
+  AddressSanitizer(
+      Module &M, const StackSafetyGlobalInfo *SSGI, bool CompileKernel = false,
+      bool Recover = false, bool UseAfterScope = false,
+      AsanDetectStackUseAfterReturnMode UseAfterReturn =
+          AsanDetectStackUseAfterReturnMode::Runtime,
+      int InstrumentationWithCallsThreshold =
+          llvm::InstrumentationWithCallsThreshold,
+      uint32_t MaxInlinePoisoningSize = llvm::MaxInlinePoisoningSize)
       : CompileKernel(ClEnableKasan.getNumOccurrences() > 0 ? ClEnableKasan
                                                             : CompileKernel),
         Recover(ClRecover.getNumOccurrences() > 0 ? ClRecover : Recover),
         UseAfterScope(UseAfterScope || ClUseAfterScope),
         UseAfterReturn(ClUseAfterReturn.getNumOccurrences() ? ClUseAfterReturn
                                                             : UseAfterReturn),
-        SSGI(SSGI) {
+        SSGI(SSGI),
+        InstrumentationWithCallsThreshold(
+            ClInstrumentationWithCallsThreshold.getNumOccurrences() > 0
+                ? ClInstrumentationWithCallsThreshold
+                : InstrumentationWithCallsThreshold),
+        MaxInlinePoisoningSize(ClMaxInlinePoisoningSize.getNumOccurrences() > 0
+                                   ? ClMaxInlinePoisoningSize
+                                   : MaxInlinePoisoningSize) {
     C = &(M.getContext());
     DL = &M.getDataLayout();
     LongSize = M.getDataLayout().getPointerSizeInBits();
@@ -774,6 +783,8 @@ struct AddressSanitizer {
 
   FunctionCallee AMDGPUAddressShared;
   FunctionCallee AMDGPUAddressPrivate;
+  int InstrumentationWithCallsThreshold;
+  uint32_t MaxInlinePoisoningSize;
 };
 
 class ModuleAddressSanitizer {
@@ -782,9 +793,13 @@ class ModuleAddressSanitizer {
                          bool Recover = false, bool UseGlobalsGC = true,
                          bool UseOdrIndicator = true,
                          AsanDtorKind DestructorKind = AsanDtorKind::Global,
-                         AsanCtorKind ConstructorKind = AsanCtorKind::Global)
+                         AsanCtorKind ConstructorKind = AsanCtorKind::Global,
+                         bool InsertVersionCheck = llvm::InsertVersionCheck)
       : CompileKernel(ClEnableKasan.getNumOccurrences() > 0 ? ClEnableKasan
                                                             : CompileKernel),
+        InsertVersionCheck(ClInsertVersionCheck.getNumOccurrences() > 0
+                               ? ClInsertVersionCheck
+                               : InsertVersionCheck),
         Recover(ClRecover.getNumOccurrences() > 0 ? ClRecover : Recover),
         UseGlobalsGC(UseGlobalsGC && ClUseGlobalsGC && !this->CompileKernel),
         // Enable aliases as they should have no downside with ODR indicators.
@@ -802,8 +817,7 @@ class ModuleAddressSanitizer {
         // ClWithComdat and ClUseGlobalsGC unless the frontend says it's ok to
         // do globals-gc.
         UseCtorComdat(UseGlobalsGC && ClWithComdat && !this->CompileKernel),
-        DestructorKind(DestructorKind),
-        ConstructorKind(ConstructorKind) {
+        DestructorKind(DestructorKind), ConstructorKind(ConstructorKind) {
     C = &(M.getContext());
     int LongSize = M.getDataLayout().getPointerSizeInBits();
     IntptrTy = Type::getIntNTy(*C, LongSize);
@@ -856,6 +870,7 @@ class ModuleAddressSanitizer {
   int GetAsanVersion(const Module &M) const;
 
   bool CompileKernel;
+  bool InsertVersionCheck;
   bool Recover;
   bool UseGlobalsGC;
   bool UsePrivateAlias;
@@ -1155,18 +1170,18 @@ AddressSanitizerPass::AddressSanitizerPass(
 
 PreservedAnalyses AddressSanitizerPass::run(Module &M,
                                             ModuleAnalysisManager &MAM) {
-  ModuleAddressSanitizer ModuleSanitizer(M, Options.CompileKernel,
-                                         Options.Recover, UseGlobalGC,
-                                         UseOdrIndicator, DestructorKind,
-                                         ConstructorKind);
+  ModuleAddressSanitizer ModuleSanitizer(
+      M, Options.CompileKernel, Options.Recover, UseGlobalGC, UseOdrIndicator,
+      DestructorKind, ConstructorKind, Options.InsertVersionCheck);
   bool Modified = false;
   auto &FAM = MAM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
   const StackSafetyGlobalInfo *const SSGI =
       ClUseStackSafety ? &MAM.getResult<StackSafetyGlobalAnalysis>(M) : nullptr;
   for (Function &F : M) {
-    AddressSanitizer FunctionSanitizer(M, SSGI, Options.CompileKernel,
-                                       Options.Recover, Options.UseAfterScope,
-                                       Options.UseAfterReturn);
+    AddressSanitizer FunctionSanitizer(
+        M, SSGI, Options.CompileKernel, Options.Recover, Options.UseAfterScope,
+        Options.UseAfterReturn, Options.InstrumentationWithCallsThreshold,
+        Options.MaxInlinePoisoningSize);
     const TargetLibraryInfo &TLI = FAM.getResult<TargetLibraryAnalysis>(F);
     Modified |= FunctionSanitizer.instrumentFunction(F, &TLI);
   }
@@ -2591,7 +2606,7 @@ bool ModuleAddressSanitizer::instrumentModule(Module &M) {
     } else {
       std::string AsanVersion = std::to_string(GetAsanVersion(M));
       std::string VersionCheckName =
-          ClInsertVersionCheck ? (kAsanVersionCheckNamePrefix + AsanVersion) : "";
+          InsertVersionCheck ? (kAsanVersionCheckNamePrefix + AsanVersion) : "";
       std::tie(AsanCtorFunction, std::ignore) =
           createSanitizerCtorAndInitFunctions(M, kAsanModuleCtorName,
                                               kAsanInitName, /*InitArgTypes=*/{},
@@ -2890,9 +2905,9 @@ bool AddressSanitizer::instrumentFunction(Function &F,
     }
   }
 
-  bool UseCalls = (ClInstrumentationWithCallsThreshold >= 0 &&
+  bool UseCalls = (InstrumentationWithCallsThreshold >= 0 &&
                    OperandsToInstrument.size() + IntrinToInstrument.size() >
-                       (unsigned)ClInstrumentationWithCallsThreshold);
+                       (unsigned)InstrumentationWithCallsThreshold);
   const DataLayout &DL = F.getParent()->getDataLayout();
   ObjectSizeOpts ObjSizeOpts;
   ObjSizeOpts.RoundToAlign = true;
@@ -3066,7 +3081,7 @@ void FunctionStackPoisoner::copyToShadow(ArrayRef<uint8_t> ShadowMask,
     for (; j < End && ShadowMask[j] && Val == ShadowBytes[j]; ++j) {
     }
 
-    if (j - i >= ClMaxInlinePoisoningSize) {
+    if (j - i >= ASan.MaxInlinePoisoningSize) {
       copyToShadowInline(ShadowMask, ShadowBytes, Done, i, IRB, ShadowBase);
       IRB.CreateCall(AsanSetShadowFunc[Val],
                      {IRB.CreateAdd(ShadowBase, ConstantInt::get(IntptrTy, i)),



More information about the llvm-commits mailing list