25
25
#include " llvm/ADT/Twine.h"
26
26
#include " llvm/Analysis/MemoryBuiltins.h"
27
27
#include " llvm/Analysis/TargetLibraryInfo.h"
28
- #include " llvm/Transforms/Utils/Local.h"
29
28
#include " llvm/Analysis/ValueTracking.h"
30
29
#include " llvm/BinaryFormat/MachO.h"
31
30
#include " llvm/IR/Argument.h"
70
69
#include " llvm/Support/ScopedPrinter.h"
71
70
#include " llvm/Support/raw_ostream.h"
72
71
#include " llvm/Transforms/Instrumentation.h"
72
+ #include " llvm/Transforms/Instrumentation/AddressSanitizerPass.h"
73
73
#include " llvm/Transforms/Utils/ASanStackFrameLayout.h"
74
74
#include " llvm/Transforms/Utils/BasicBlockUtils.h"
75
+ #include " llvm/Transforms/Utils/Local.h"
75
76
#include " llvm/Transforms/Utils/ModuleUtils.h"
76
77
#include " llvm/Transforms/Utils/PromoteMemToReg.h"
77
78
#include < algorithm>
@@ -597,26 +598,22 @@ static size_t RedzoneSizeForScale(int MappingScale) {
597
598
namespace {
598
599
599
600
// / 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 ,
605
604
bool UseAfterScope = false )
606
- : FunctionPass(ID), UseAfterScope(UseAfterScope || ClUseAfterScope) {
605
+ : UseAfterScope(UseAfterScope || ClUseAfterScope), DT(DT ) {
607
606
this ->Recover = ClRecover.getNumOccurrences () > 0 ? ClRecover : Recover;
608
607
this ->CompileKernel = ClEnableKasan.getNumOccurrences () > 0 ?
609
608
ClEnableKasan : CompileKernel;
610
- initializeAddressSanitizerPass (*PassRegistry::getPassRegistry ());
611
- }
612
-
613
- StringRef getPassName () const override {
614
- return " AddressSanitizerFunctionPass" ;
615
- }
616
609
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);
620
617
}
621
618
622
619
uint64_t getAllocaSizeInBytes (const AllocaInst &AI) const {
@@ -661,12 +658,12 @@ struct AddressSanitizer : public FunctionPass {
661
658
Value *SizeArgument, uint32_t Exp);
662
659
void instrumentMemIntrinsic (MemIntrinsic *MI);
663
660
Value *memToShadow (Value *Shadow, IRBuilder<> &IRB);
664
- bool runOnFunction (Function &F) override ;
665
661
bool maybeInsertAsanInitAtFunctionEntry (Function &F);
666
662
void maybeInsertDynamicShadowAtFunctionEntry (Function &F);
667
663
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);
670
667
671
668
DominatorTree &getDominatorTree () const { return *DT; }
672
669
@@ -724,16 +721,12 @@ struct AddressSanitizer : public FunctionPass {
724
721
DenseMap<const AllocaInst *, bool > ProcessedAllocas;
725
722
};
726
723
727
- class AddressSanitizerModule : public ModulePass {
724
+ class AddressSanitizerModule {
728
725
public:
729
- // Pass identification, replacement for typeid
730
- static char ID;
731
-
732
726
explicit AddressSanitizerModule (bool CompileKernel = false ,
733
727
bool Recover = false ,
734
728
bool UseGlobalsGC = true )
735
- : ModulePass(ID),
736
- UseGlobalsGC(UseGlobalsGC && ClUseGlobalsGC),
729
+ : UseGlobalsGC(UseGlobalsGC && ClUseGlobalsGC),
737
730
// Not a typo: ClWithComdat is almost completely pointless without
738
731
// ClUseGlobalsGC (because then it only works on modules without
739
732
// globals, which are rare); it is a prerequisite for ClUseGlobalsGC;
@@ -742,14 +735,12 @@ class AddressSanitizerModule : public ModulePass {
742
735
// ClWithComdat and ClUseGlobalsGC unless the frontend says it's ok to
743
736
// do globals-gc.
744
737
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
+ }
750
742
751
- bool runOnModule (Module &M) override ;
752
- StringRef getPassName () const override { return " AddressSanitizerModule" ; }
743
+ bool instrument (Module &M);
753
744
754
745
private:
755
746
void initializeCallbacks (Module &M);
@@ -1057,32 +1048,114 @@ struct FunctionStackPoisoner : public InstVisitor<FunctionStackPoisoner> {
1057
1048
Instruction *ThenTerm, Value *ValueIfFalse);
1058
1049
};
1059
1050
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
+
1060
1109
} // end anonymous namespace
1061
1110
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 ;
1063
1136
1064
1137
INITIALIZE_PASS_BEGIN (
1065
- AddressSanitizer , " asan" ,
1138
+ AddressSanitizerLegacyPass , " asan" ,
1066
1139
" AddressSanitizer: detects use-after-free and out-of-bounds bugs." , false ,
1067
1140
false )
1068
1141
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
1069
1142
INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
1070
1143
INITIALIZE_PASS_END(
1071
- AddressSanitizer , " asan" ,
1144
+ AddressSanitizerLegacyPass , " asan" ,
1072
1145
" AddressSanitizer: detects use-after-free and out-of-bounds bugs." , false ,
1073
1146
false )
1074
1147
1075
1148
FunctionPass *llvm::createAddressSanitizerFunctionPass(bool CompileKernel,
1076
1149
bool Recover,
1077
1150
bool UseAfterScope) {
1078
1151
assert (!CompileKernel || Recover);
1079
- return new AddressSanitizer (CompileKernel, Recover, UseAfterScope);
1152
+ return new AddressSanitizerLegacyPass (CompileKernel, Recover, UseAfterScope);
1080
1153
}
1081
1154
1082
- char AddressSanitizerModule ::ID = 0 ;
1155
+ char AddressSanitizerModuleLegacyPass ::ID = 0 ;
1083
1156
1084
1157
INITIALIZE_PASS (
1085
- AddressSanitizerModule , " asan-module" ,
1158
+ AddressSanitizerModuleLegacyPass , " asan-module" ,
1086
1159
" AddressSanitizer: detects use-after-free and out-of-bounds bugs."
1087
1160
" ModulePass" ,
1088
1161
false , false )
@@ -1091,7 +1164,8 @@ ModulePass *llvm::createAddressSanitizerModulePass(bool CompileKernel,
1091
1164
bool Recover,
1092
1165
bool UseGlobalsGC) {
1093
1166
assert (!CompileKernel || Recover);
1094
- return new AddressSanitizerModule (CompileKernel, Recover, UseGlobalsGC);
1167
+ return new AddressSanitizerModuleLegacyPass (CompileKernel, Recover,
1168
+ UseGlobalsGC);
1095
1169
}
1096
1170
1097
1171
static size_t TypeSizeToSizeIndex (uint32_t TypeSize) {
@@ -2268,7 +2342,7 @@ int AddressSanitizerModule::GetAsanVersion(const Module &M) const {
2268
2342
return Version;
2269
2343
}
2270
2344
2271
- bool AddressSanitizerModule::runOnModule (Module &M) {
2345
+ bool AddressSanitizerModule::instrument (Module &M) {
2272
2346
C = &(M.getContext ());
2273
2347
int LongSize = M.getDataLayout ().getPointerSizeInBits ();
2274
2348
IntptrTy = Type::getIntNTy (*C, LongSize);
@@ -2387,25 +2461,6 @@ void AddressSanitizer::initializeCallbacks(Module &M) {
2387
2461
ArrayType::get (IRB.getInt8Ty (), 0 ));
2388
2462
}
2389
2463
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
-
2409
2464
bool AddressSanitizer::maybeInsertAsanInitAtFunctionEntry (Function &F) {
2410
2465
// For each NSObject descendant having a +load method, this method is invoked
2411
2466
// by the ObjC runtime before any of the static constructors is called.
@@ -2479,7 +2534,7 @@ void AddressSanitizer::markEscapedLocalAllocas(Function &F) {
2479
2534
}
2480
2535
}
2481
2536
2482
- bool AddressSanitizer::runOnFunction (Function &F) {
2537
+ bool AddressSanitizer::instrument (Function &F, const TargetLibraryInfo *TLI ) {
2483
2538
if (F.getLinkage () == GlobalValue::AvailableExternallyLinkage) return false ;
2484
2539
if (!ClDebugFunc.empty () && ClDebugFunc == F.getName ()) return false ;
2485
2540
if (F.getName ().startswith (" __asan_" )) return false ;
@@ -2498,7 +2553,6 @@ bool AddressSanitizer::runOnFunction(Function &F) {
2498
2553
LLVM_DEBUG (dbgs () << " ASAN instrumenting:\n " << F << " \n " );
2499
2554
2500
2555
initializeCallbacks (*F.getParent ());
2501
- DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree ();
2502
2556
2503
2557
FunctionStateRAII CleanupObj (this );
2504
2558
@@ -2519,8 +2573,6 @@ bool AddressSanitizer::runOnFunction(Function &F) {
2519
2573
bool IsWrite;
2520
2574
unsigned Alignment;
2521
2575
uint64_t TypeSize;
2522
- const TargetLibraryInfo *TLI =
2523
- &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI ();
2524
2576
2525
2577
// Fill the set of memory operations to instrument.
2526
2578
for (auto &BB : F) {
0 commit comments