[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