Skip to content

Commit 64e21b5

Browse files
committedOct 11, 2018
[PassManager/Sanitizer] Port of AddresSanitizer pass from legacy to new PassManager
This patch ports the legacy pass manager to the new one to take advantage of the benefits of the new PM. This involved moving a lot of the declarations for `AddressSantizer` to a header so that it can be publicly used via PassRegistry.def which I believe contains all the passes managed by the new PM. This patch essentially decouples the instrumentation from the legacy PM such hat it can be used by both legacy and new PM infrastructure. Differential Revision: https://reviews.llvm.org/D52739 llvm-svn: 344274
1 parent ff23bb6 commit 64e21b5

File tree

7 files changed

+166
-68
lines changed

7 files changed

+166
-68
lines changed
 

‎llvm/include/llvm/InitializePasses.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,8 @@ void initializeAAEvalLegacyPassPass(PassRegistry&);
6565
void initializeAAResultsWrapperPassPass(PassRegistry&);
6666
void initializeADCELegacyPassPass(PassRegistry&);
6767
void initializeAddDiscriminatorsLegacyPassPass(PassRegistry&);
68-
void initializeAddressSanitizerModulePass(PassRegistry&);
69-
void initializeAddressSanitizerPass(PassRegistry&);
68+
void initializeAddressSanitizerModuleLegacyPassPass(PassRegistry &);
69+
void initializeAddressSanitizerLegacyPassPass(PassRegistry &);
7070
void initializeAggressiveInstCombinerLegacyPassPass(PassRegistry&);
7171
void initializeAliasSetPrinterPass(PassRegistry&);
7272
void initializeAlignmentFromAssumptionsPass(PassRegistry&);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
//===--------- Definition of the AddressSanitizer class ---------*- C++ -*-===//
2+
//
3+
// The LLVM Compiler Infrastructure
4+
//
5+
// This file is distributed under the University of Illinois Open Source
6+
// License. See LICENSE.TXT for details.
7+
//
8+
//===----------------------------------------------------------------------===//
9+
//
10+
// This file declares the AddressSanitizer class which is a port of the legacy
11+
// AddressSanitizer pass to use the new PassManager infrastructure.
12+
//
13+
//===----------------------------------------------------------------------===//
14+
#ifndef LLVM_TRANSFORMS_INSTRUMENTATION_ADDRESSSANITIZERPASS_H
15+
#define LLVM_TRANSFORMS_INSTRUMENTATION_ADDRESSSANITIZERPASS_H
16+
17+
#include "llvm/IR/Function.h"
18+
#include "llvm/IR/Module.h"
19+
#include "llvm/IR/PassManager.h"
20+
21+
namespace llvm {
22+
23+
/// Public interface to the address sanitizer pass for instrumenting code to
24+
/// check for various memory bugs.
25+
class AddressSanitizerPass : public PassInfoMixin<AddressSanitizerPass> {
26+
public:
27+
explicit AddressSanitizerPass(bool CompileKernel = false,
28+
bool Recover = false,
29+
bool UseAfterScope = false);
30+
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
31+
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
32+
33+
private:
34+
bool CompileKernel;
35+
bool Recover;
36+
bool UseAfterScope;
37+
};
38+
39+
} // namespace llvm
40+
41+
#endif

‎llvm/lib/Passes/PassBuilder.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,6 @@
6161
#include "llvm/Support/Regex.h"
6262
#include "llvm/Target/TargetMachine.h"
6363
#include "llvm/Transforms/AggressiveInstCombine/AggressiveInstCombine.h"
64-
#include "llvm/Transforms/Instrumentation/CGProfile.h"
6564
#include "llvm/Transforms/IPO/AlwaysInliner.h"
6665
#include "llvm/Transforms/IPO/ArgumentPromotion.h"
6766
#include "llvm/Transforms/IPO/CalledValuePropagation.h"
@@ -87,7 +86,9 @@
8786
#include "llvm/Transforms/IPO/SyntheticCountsPropagation.h"
8887
#include "llvm/Transforms/IPO/WholeProgramDevirt.h"
8988
#include "llvm/Transforms/InstCombine/InstCombine.h"
89+
#include "llvm/Transforms/Instrumentation/AddressSanitizerPass.h"
9090
#include "llvm/Transforms/Instrumentation/BoundsChecking.h"
91+
#include "llvm/Transforms/Instrumentation/CGProfile.h"
9192
#include "llvm/Transforms/Instrumentation/ControlHeightReduction.h"
9293
#include "llvm/Transforms/Instrumentation/GCOVProfiler.h"
9394
#include "llvm/Transforms/Instrumentation/InstrProfiling.h"

‎llvm/lib/Passes/PassRegistry.def

+2
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ MODULE_ALIAS_ANALYSIS("globals-aa", GlobalsAA())
4040
#define MODULE_PASS(NAME, CREATE_PASS)
4141
#endif
4242
MODULE_PASS("always-inline", AlwaysInlinerPass())
43+
MODULE_PASS("asan", AddressSanitizerPass(false, false, true))
4344
MODULE_PASS("called-value-propagation", CalledValuePropagationPass())
4445
MODULE_PASS("cg-profile", CGProfilePass())
4546
MODULE_PASS("constmerge", ConstantMergePass())
@@ -147,6 +148,7 @@ FUNCTION_PASS("adce", ADCEPass())
147148
FUNCTION_PASS("add-discriminators", AddDiscriminatorsPass())
148149
FUNCTION_PASS("aggressive-instcombine", AggressiveInstCombinePass())
149150
FUNCTION_PASS("alignment-from-assumptions", AlignmentFromAssumptionsPass())
151+
FUNCTION_PASS("asan", AddressSanitizerPass(false, false, false))
150152
FUNCTION_PASS("bdce", BDCEPass())
151153
FUNCTION_PASS("bounds-checking", BoundsCheckingPass())
152154
FUNCTION_PASS("break-crit-edges", BreakCriticalEdgesPass())

‎llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp

+115-63
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525
#include "llvm/ADT/Twine.h"
2626
#include "llvm/Analysis/MemoryBuiltins.h"
2727
#include "llvm/Analysis/TargetLibraryInfo.h"
28-
#include "llvm/Transforms/Utils/Local.h"
2928
#include "llvm/Analysis/ValueTracking.h"
3029
#include "llvm/BinaryFormat/MachO.h"
3130
#include "llvm/IR/Argument.h"
@@ -70,8 +69,10 @@
7069
#include "llvm/Support/ScopedPrinter.h"
7170
#include "llvm/Support/raw_ostream.h"
7271
#include "llvm/Transforms/Instrumentation.h"
72+
#include "llvm/Transforms/Instrumentation/AddressSanitizerPass.h"
7373
#include "llvm/Transforms/Utils/ASanStackFrameLayout.h"
7474
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
75+
#include "llvm/Transforms/Utils/Local.h"
7576
#include "llvm/Transforms/Utils/ModuleUtils.h"
7677
#include "llvm/Transforms/Utils/PromoteMemToReg.h"
7778
#include <algorithm>
@@ -597,26 +598,22 @@ static size_t RedzoneSizeForScale(int MappingScale) {
597598
namespace {
598599

599600
/// AddressSanitizer: instrument the code in module to find memory bugs.
600-
struct AddressSanitizer : public FunctionPass {
601-
// Pass identification, replacement for typeid
602-
static char ID;
603-
604-
explicit AddressSanitizer(bool CompileKernel = false, bool Recover = false,
601+
struct AddressSanitizer {
602+
explicit AddressSanitizer(Module &M, DominatorTree *DT,
603+
bool CompileKernel = false, bool Recover = false,
605604
bool UseAfterScope = false)
606-
: FunctionPass(ID), UseAfterScope(UseAfterScope || ClUseAfterScope) {
605+
: UseAfterScope(UseAfterScope || ClUseAfterScope), DT(DT) {
607606
this->Recover = ClRecover.getNumOccurrences() > 0 ? ClRecover : Recover;
608607
this->CompileKernel = ClEnableKasan.getNumOccurrences() > 0 ?
609608
ClEnableKasan : CompileKernel;
610-
initializeAddressSanitizerPass(*PassRegistry::getPassRegistry());
611-
}
612-
613-
StringRef getPassName() const override {
614-
return "AddressSanitizerFunctionPass";
615-
}
616609

617-
void getAnalysisUsage(AnalysisUsage &AU) const override {
618-
AU.addRequired<DominatorTreeWrapperPass>();
619-
AU.addRequired<TargetLibraryInfoWrapperPass>();
610+
// Initialize the private fields. No one has accessed them before.
611+
GlobalsMD.init(M);
612+
C = &(M.getContext());
613+
LongSize = M.getDataLayout().getPointerSizeInBits();
614+
IntptrTy = Type::getIntNTy(*C, LongSize);
615+
TargetTriple = Triple(M.getTargetTriple());
616+
Mapping = getShadowMapping(TargetTriple, LongSize, CompileKernel);
620617
}
621618

622619
uint64_t getAllocaSizeInBytes(const AllocaInst &AI) const {
@@ -661,12 +658,12 @@ struct AddressSanitizer : public FunctionPass {
661658
Value *SizeArgument, uint32_t Exp);
662659
void instrumentMemIntrinsic(MemIntrinsic *MI);
663660
Value *memToShadow(Value *Shadow, IRBuilder<> &IRB);
664-
bool runOnFunction(Function &F) override;
665661
bool maybeInsertAsanInitAtFunctionEntry(Function &F);
666662
void maybeInsertDynamicShadowAtFunctionEntry(Function &F);
667663
void markEscapedLocalAllocas(Function &F);
668-
bool doInitialization(Module &M) override;
669-
bool doFinalization(Module &M) override;
664+
665+
/// Return true if the function changed.
666+
bool instrument(Function &F, const TargetLibraryInfo *TLI);
670667

671668
DominatorTree &getDominatorTree() const { return *DT; }
672669

@@ -724,16 +721,12 @@ struct AddressSanitizer : public FunctionPass {
724721
DenseMap<const AllocaInst *, bool> ProcessedAllocas;
725722
};
726723

727-
class AddressSanitizerModule : public ModulePass {
724+
class AddressSanitizerModule {
728725
public:
729-
// Pass identification, replacement for typeid
730-
static char ID;
731-
732726
explicit AddressSanitizerModule(bool CompileKernel = false,
733727
bool Recover = false,
734728
bool UseGlobalsGC = true)
735-
: ModulePass(ID),
736-
UseGlobalsGC(UseGlobalsGC && ClUseGlobalsGC),
729+
: UseGlobalsGC(UseGlobalsGC && ClUseGlobalsGC),
737730
// Not a typo: ClWithComdat is almost completely pointless without
738731
// ClUseGlobalsGC (because then it only works on modules without
739732
// globals, which are rare); it is a prerequisite for ClUseGlobalsGC;
@@ -742,14 +735,12 @@ class AddressSanitizerModule : public ModulePass {
742735
// ClWithComdat and ClUseGlobalsGC unless the frontend says it's ok to
743736
// do globals-gc.
744737
UseCtorComdat(UseGlobalsGC && ClWithComdat) {
745-
this->Recover = ClRecover.getNumOccurrences() > 0 ?
746-
ClRecover : Recover;
747-
this->CompileKernel = ClEnableKasan.getNumOccurrences() > 0 ?
748-
ClEnableKasan : CompileKernel;
749-
}
738+
this->Recover = ClRecover.getNumOccurrences() > 0 ? ClRecover : Recover;
739+
this->CompileKernel =
740+
ClEnableKasan.getNumOccurrences() > 0 ? ClEnableKasan : CompileKernel;
741+
}
750742

751-
bool runOnModule(Module &M) override;
752-
StringRef getPassName() const override { return "AddressSanitizerModule"; }
743+
bool instrument(Module &M);
753744

754745
private:
755746
void initializeCallbacks(Module &M);
@@ -1057,32 +1048,114 @@ struct FunctionStackPoisoner : public InstVisitor<FunctionStackPoisoner> {
10571048
Instruction *ThenTerm, Value *ValueIfFalse);
10581049
};
10591050

1051+
class AddressSanitizerLegacyPass : public FunctionPass {
1052+
public:
1053+
static char ID;
1054+
1055+
explicit AddressSanitizerLegacyPass(bool CompileKernel = false,
1056+
bool Recover = false,
1057+
bool UseAfterScope = false)
1058+
: FunctionPass(ID), CompileKernel(CompileKernel), Recover(Recover),
1059+
UseAfterScope(UseAfterScope) {}
1060+
1061+
StringRef getPassName() const override {
1062+
return "AddressSanitizerFunctionPass";
1063+
}
1064+
1065+
void getAnalysisUsage(AnalysisUsage &AU) const override {
1066+
AU.addRequired<DominatorTreeWrapperPass>();
1067+
AU.addRequired<TargetLibraryInfoWrapperPass>();
1068+
}
1069+
1070+
bool runOnFunction(Function &F) override {
1071+
DominatorTree *DTree =
1072+
&getAnalysis<DominatorTreeWrapperPass>().getDomTree();
1073+
const TargetLibraryInfo *TLI =
1074+
&getAnalysis<TargetLibraryInfoWrapperPass>().getTLI();
1075+
AddressSanitizer Sanitizer(*F.getParent(), DTree, CompileKernel, Recover,
1076+
UseAfterScope);
1077+
return Sanitizer.instrument(F, TLI);
1078+
}
1079+
1080+
private:
1081+
bool CompileKernel;
1082+
bool Recover;
1083+
bool UseAfterScope;
1084+
};
1085+
1086+
class AddressSanitizerModuleLegacyPass : public ModulePass {
1087+
public:
1088+
static char ID;
1089+
1090+
explicit AddressSanitizerModuleLegacyPass(bool CompileKernel = false,
1091+
bool Recover = false,
1092+
bool UseAfterScope = true)
1093+
: ModulePass(ID), CompileKernel(CompileKernel), Recover(Recover),
1094+
UseAfterScope(UseAfterScope) {}
1095+
1096+
StringRef getPassName() const override { return "AddressSanitizerModule"; }
1097+
1098+
bool runOnModule(Module &M) override {
1099+
AddressSanitizerModule Sanitizer(CompileKernel, Recover, UseAfterScope);
1100+
return Sanitizer.instrument(M);
1101+
}
1102+
1103+
private:
1104+
bool CompileKernel;
1105+
bool Recover;
1106+
bool UseAfterScope;
1107+
};
1108+
10601109
} // end anonymous namespace
10611110

1062-
char AddressSanitizer::ID = 0;
1111+
AddressSanitizerPass::AddressSanitizerPass(bool CompileKernel, bool Recover,
1112+
bool UseAfterScope)
1113+
: CompileKernel(CompileKernel), Recover(Recover),
1114+
UseAfterScope(UseAfterScope) {}
1115+
1116+
PreservedAnalyses AddressSanitizerPass::run(Function &F,
1117+
AnalysisManager<Function> &AM) {
1118+
DominatorTree *DT = &AM.getResult<DominatorTreeAnalysis>(F);
1119+
const TargetLibraryInfo *TLI = &AM.getResult<TargetLibraryAnalysis>(F);
1120+
AddressSanitizer Sanitizer(*F.getParent(), DT, CompileKernel, Recover,
1121+
UseAfterScope);
1122+
if (Sanitizer.instrument(F, TLI))
1123+
return PreservedAnalyses::none();
1124+
return PreservedAnalyses::all();
1125+
}
1126+
1127+
PreservedAnalyses AddressSanitizerPass::run(Module &M,
1128+
AnalysisManager<Module> &AM) {
1129+
AddressSanitizerModule Sanitizer(CompileKernel, Recover, UseAfterScope);
1130+
if (Sanitizer.instrument(M))
1131+
return PreservedAnalyses::none();
1132+
return PreservedAnalyses::all();
1133+
}
1134+
1135+
char AddressSanitizerLegacyPass::ID = 0;
10631136

10641137
INITIALIZE_PASS_BEGIN(
1065-
AddressSanitizer, "asan",
1138+
AddressSanitizerLegacyPass, "asan",
10661139
"AddressSanitizer: detects use-after-free and out-of-bounds bugs.", false,
10671140
false)
10681141
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
10691142
INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
10701143
INITIALIZE_PASS_END(
1071-
AddressSanitizer, "asan",
1144+
AddressSanitizerLegacyPass, "asan",
10721145
"AddressSanitizer: detects use-after-free and out-of-bounds bugs.", false,
10731146
false)
10741147

10751148
FunctionPass *llvm::createAddressSanitizerFunctionPass(bool CompileKernel,
10761149
bool Recover,
10771150
bool UseAfterScope) {
10781151
assert(!CompileKernel || Recover);
1079-
return new AddressSanitizer(CompileKernel, Recover, UseAfterScope);
1152+
return new AddressSanitizerLegacyPass(CompileKernel, Recover, UseAfterScope);
10801153
}
10811154

1082-
char AddressSanitizerModule::ID = 0;
1155+
char AddressSanitizerModuleLegacyPass::ID = 0;
10831156

10841157
INITIALIZE_PASS(
1085-
AddressSanitizerModule, "asan-module",
1158+
AddressSanitizerModuleLegacyPass, "asan-module",
10861159
"AddressSanitizer: detects use-after-free and out-of-bounds bugs."
10871160
"ModulePass",
10881161
false, false)
@@ -1091,7 +1164,8 @@ ModulePass *llvm::createAddressSanitizerModulePass(bool CompileKernel,
10911164
bool Recover,
10921165
bool UseGlobalsGC) {
10931166
assert(!CompileKernel || Recover);
1094-
return new AddressSanitizerModule(CompileKernel, Recover, UseGlobalsGC);
1167+
return new AddressSanitizerModuleLegacyPass(CompileKernel, Recover,
1168+
UseGlobalsGC);
10951169
}
10961170

10971171
static size_t TypeSizeToSizeIndex(uint32_t TypeSize) {
@@ -2268,7 +2342,7 @@ int AddressSanitizerModule::GetAsanVersion(const Module &M) const {
22682342
return Version;
22692343
}
22702344

2271-
bool AddressSanitizerModule::runOnModule(Module &M) {
2345+
bool AddressSanitizerModule::instrument(Module &M) {
22722346
C = &(M.getContext());
22732347
int LongSize = M.getDataLayout().getPointerSizeInBits();
22742348
IntptrTy = Type::getIntNTy(*C, LongSize);
@@ -2387,25 +2461,6 @@ void AddressSanitizer::initializeCallbacks(Module &M) {
23872461
ArrayType::get(IRB.getInt8Ty(), 0));
23882462
}
23892463

2390-
// virtual
2391-
bool AddressSanitizer::doInitialization(Module &M) {
2392-
// Initialize the private fields. No one has accessed them before.
2393-
GlobalsMD.init(M);
2394-
2395-
C = &(M.getContext());
2396-
LongSize = M.getDataLayout().getPointerSizeInBits();
2397-
IntptrTy = Type::getIntNTy(*C, LongSize);
2398-
TargetTriple = Triple(M.getTargetTriple());
2399-
2400-
Mapping = getShadowMapping(TargetTriple, LongSize, CompileKernel);
2401-
return true;
2402-
}
2403-
2404-
bool AddressSanitizer::doFinalization(Module &M) {
2405-
GlobalsMD.reset();
2406-
return false;
2407-
}
2408-
24092464
bool AddressSanitizer::maybeInsertAsanInitAtFunctionEntry(Function &F) {
24102465
// For each NSObject descendant having a +load method, this method is invoked
24112466
// by the ObjC runtime before any of the static constructors is called.
@@ -2479,7 +2534,7 @@ void AddressSanitizer::markEscapedLocalAllocas(Function &F) {
24792534
}
24802535
}
24812536

2482-
bool AddressSanitizer::runOnFunction(Function &F) {
2537+
bool AddressSanitizer::instrument(Function &F, const TargetLibraryInfo *TLI) {
24832538
if (F.getLinkage() == GlobalValue::AvailableExternallyLinkage) return false;
24842539
if (!ClDebugFunc.empty() && ClDebugFunc == F.getName()) return false;
24852540
if (F.getName().startswith("__asan_")) return false;
@@ -2498,7 +2553,6 @@ bool AddressSanitizer::runOnFunction(Function &F) {
24982553
LLVM_DEBUG(dbgs() << "ASAN instrumenting:\n" << F << "\n");
24992554

25002555
initializeCallbacks(*F.getParent());
2501-
DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
25022556

25032557
FunctionStateRAII CleanupObj(this);
25042558

@@ -2519,8 +2573,6 @@ bool AddressSanitizer::runOnFunction(Function &F) {
25192573
bool IsWrite;
25202574
unsigned Alignment;
25212575
uint64_t TypeSize;
2522-
const TargetLibraryInfo *TLI =
2523-
&getAnalysis<TargetLibraryInfoWrapperPass>().getTLI();
25242576

25252577
// Fill the set of memory operations to instrument.
25262578
for (auto &BB : F) {

‎llvm/lib/Transforms/Instrumentation/Instrumentation.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,8 @@ BasicBlock::iterator llvm::PrepareToSplitEntryBlock(BasicBlock &BB,
5656
/// initializeInstrumentation - Initialize all passes in the TransformUtils
5757
/// library.
5858
void llvm::initializeInstrumentation(PassRegistry &Registry) {
59-
initializeAddressSanitizerPass(Registry);
60-
initializeAddressSanitizerModulePass(Registry);
59+
initializeAddressSanitizerLegacyPassPass(Registry);
60+
initializeAddressSanitizerModuleLegacyPassPass(Registry);
6161
initializeBoundsCheckingLegacyPassPass(Registry);
6262
initializeControlHeightReductionLegacyPassPass(Registry);
6363
initializeGCOVProfilerLegacyPassPass(Registry);

‎llvm/test/Instrumentation/AddressSanitizer/basic.ll

+2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
; Test basic address sanitizer instrumentation.
22
;
33
; RUN: opt < %s -asan -asan-module -S | FileCheck --check-prefixes=CHECK,CHECK-S3 %s
4+
; RUN: opt < %s -passes='function(asan),module(asan)' -S | FileCheck --check-prefixes=CHECK,CHECK-S3 %s
45
; RUN: opt < %s -asan -asan-module -asan-mapping-scale=5 -S | FileCheck --check-prefixes=CHECK,CHECK-S5 %s
6+
; RUN: opt < %s -passes='function(asan),module(asan)' -asan-mapping-scale=5 -S | FileCheck --check-prefixes=CHECK,CHECK-S5 %s
57

68
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"
79
target triple = "x86_64-unknown-linux-gnu"

0 commit comments

Comments
 (0)
Please sign in to comment.