llvm.org GIT mirror llvm / e6d329d
Revert 374481 "[tsan,msan] Insert module constructors in a module pass" CodeGen/sanitizer-module-constructor.c fails on mac and windows, see e.g. http://lab.llvm.org:8011/builders/clang-x64-windows-msvc/builds/11424 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@374503 91177308-0d34-0410-b5e6-96231b3b80d8 Nico Weber 1 year, 1 month ago
7 changed file(s) with 53 addition(s) and 69 deletion(s). Raw diff Collapse all Expand all
3939 MemorySanitizerPass(MemorySanitizerOptions Options) : Options(Options) {}
4040
4141 PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM);
42 PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
4342
4443 private:
4544 MemorySanitizerOptions Options;
2626 /// yet, the pass inserts the declarations. Otherwise the existing globals are
2727 struct ThreadSanitizerPass : public PassInfoMixin {
2828 PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM);
29 PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
3029 };
31
3230 } // namespace llvm
3331 #endif /* LLVM_TRANSFORMS_INSTRUMENTATION_THREADSANITIZER_H */
8585 MODULE_PASS("wholeprogramdevirt", WholeProgramDevirtPass(nullptr, nullptr))
8686 MODULE_PASS("verify", VerifierPass())
8787 MODULE_PASS("asan-module", ModuleAddressSanitizerPass(/*CompileKernel=*/false, false, true, false))
88 MODULE_PASS("msan-module", MemorySanitizerPass({}))
89 MODULE_PASS("tsan-module", ThreadSanitizerPass())
9088 MODULE_PASS("kasan-module", ModuleAddressSanitizerPass(/*CompileKernel=*/true, false, true, false))
9189 MODULE_PASS("sancov-module", ModuleSanitizerCoveragePass())
9290 MODULE_PASS("poison-checking", PoisonCheckingPass())
586586
587587 /// An empty volatile inline asm that prevents callback merge.
588588 InlineAsm *EmptyAsm;
589
590 Function *MsanCtorFunction;
589591 };
590
591 void insertModuleCtor(Module &M) {
592 getOrCreateSanitizerCtorAndInitFunctions(
593 M, kMsanModuleCtorName, kMsanInitName,
594 /*InitArgTypes=*/{},
595 /*InitArgs=*/{},
596 // This callback is invoked when the functions are created the first
597 // time. Hook them into the global ctors list in that case:
598 [&](Function *Ctor, FunctionCallee) {
599 if (!ClWithComdat) {
600 appendToGlobalCtors(M, Ctor, 0);
601 return;
602 }
603 Comdat *MsanCtorComdat = M.getOrInsertComdat(kMsanModuleCtorName);
604 Ctor->setComdat(MsanCtorComdat);
605 appendToGlobalCtors(M, Ctor, 0, Ctor);
606 });
607 }
608592
609593 /// A legacy function pass for msan instrumentation.
610594 ///
648632 if (Msan.sanitizeFunction(F, FAM.getResult(F)))
649633 return PreservedAnalyses::none();
650634 return PreservedAnalyses::all();
651 }
652
653 PreservedAnalyses MemorySanitizerPass::run(Module &M,
654 ModuleAnalysisManager &AM) {
655 if (Options.Kernel)
656 return PreservedAnalyses::all();
657 insertModuleCtor(M);
658 return PreservedAnalyses::none();
659635 }
660636
661637 char MemorySanitizerLegacyPass::ID = 0;
943919 OriginStoreWeights = MDBuilder(*C).createBranchWeights(1, 1000);
944920
945921 if (!CompileKernel) {
922 std::tie(MsanCtorFunction, std::ignore) =
923 getOrCreateSanitizerCtorAndInitFunctions(
924 M, kMsanModuleCtorName, kMsanInitName,
925 /*InitArgTypes=*/{},
926 /*InitArgs=*/{},
927 // This callback is invoked when the functions are created the first
928 // time. Hook them into the global ctors list in that case:
929 [&](Function *Ctor, FunctionCallee) {
930 if (!ClWithComdat) {
931 appendToGlobalCtors(M, Ctor, 0);
932 return;
933 }
934 Comdat *MsanCtorComdat = M.getOrInsertComdat(kMsanModuleCtorName);
935 Ctor->setComdat(MsanCtorComdat);
936 appendToGlobalCtors(M, Ctor, 0, Ctor);
937 });
938
946939 if (TrackOrigins)
947940 M.getOrInsertGlobal("__msan_track_origins", IRB.getInt32Ty(), [&] {
948941 return new GlobalVariable(
960953 }
961954
962955 bool MemorySanitizerLegacyPass::doInitialization(Module &M) {
963 if (!Options.Kernel)
964 insertModuleCtor(M);
965956 MSan.emplace(M, Options);
966957 return true;
967958 }
45864577 }
45874578
45884579 bool MemorySanitizer::sanitizeFunction(Function &F, TargetLibraryInfo &TLI) {
4589 if (!CompileKernel && F.getName() == kMsanModuleCtorName)
4580 if (!CompileKernel && (&F == MsanCtorFunction))
45904581 return false;
4591
45924582 MemorySanitizerVisitor Visitor(F, *this, TLI);
45934583
45944584 // Clear out readonly/readnone attributes.
9191 /// ensures the __tsan_init function is in the list of global constructors for
9292 /// the module.
9393 struct ThreadSanitizer {
94 ThreadSanitizer(Module &M);
9495 bool sanitizeFunction(Function &F, const TargetLibraryInfo &TLI);
9596
9697 private:
97 void initialize(Module &M);
98 void initializeCallbacks(Module &M);
9899 bool instrumentLoadOrStore(Instruction *I, const DataLayout &DL);
99100 bool instrumentAtomic(Instruction *I, const DataLayout &DL);
100101 bool instrumentMemIntrinsic(Instruction *I);
106107 void InsertRuntimeIgnores(Function &F);
107108
108109 Type *IntptrTy;
110 IntegerType *OrdTy;
111 // Callbacks to run-time library are computed in doInitialization.
109112 FunctionCallee TsanFuncEntry;
110113 FunctionCallee TsanFuncExit;
111114 FunctionCallee TsanIgnoreBegin;
126129 FunctionCallee TsanVptrUpdate;
127130 FunctionCallee TsanVptrLoad;
128131 FunctionCallee MemmoveFn, MemcpyFn, MemsetFn;
132 Function *TsanCtorFunction;
129133 };
130134
131135 struct ThreadSanitizerLegacyPass : FunctionPass {
138142 private:
139143 Optional TSan;
140144 };
141
142 void insertModuleCtor(Module &M) {
143 getOrCreateSanitizerCtorAndInitFunctions(
144 M, kTsanModuleCtorName, kTsanInitName, /*InitArgTypes=*/{},
145 /*InitArgs=*/{},
146 // This callback is invoked when the functions are created the first
147 // time. Hook them into the global ctors list in that case:
148 [&](Function *Ctor, FunctionCallee) { appendToGlobalCtors(M, Ctor, 0); });
149 }
150
151145 } // namespace
152146
153147 PreservedAnalyses ThreadSanitizerPass::run(Function &F,
154148 FunctionAnalysisManager &FAM) {
155 ThreadSanitizer TSan;
149 ThreadSanitizer TSan(*F.getParent());
156150 if (TSan.sanitizeFunction(F, FAM.getResult(F)))
157151 return PreservedAnalyses::none();
158152 return PreservedAnalyses::all();
159 }
160
161 PreservedAnalyses ThreadSanitizerPass::run(Module &M,
162 ModuleAnalysisManager &MAM) {
163 insertModuleCtor(M);
164 return PreservedAnalyses::none();
165153 }
166154
167155 char ThreadSanitizerLegacyPass::ID = 0;
180168 }
181169
182170 bool ThreadSanitizerLegacyPass::doInitialization(Module &M) {
183 insertModuleCtor(M);
184 TSan.emplace();
171 TSan.emplace(M);
185172 return true;
186173 }
187174
195182 return new ThreadSanitizerLegacyPass();
196183 }
197184
198 void ThreadSanitizer::initialize(Module &M) {
199 const DataLayout &DL = M.getDataLayout();
200 IntptrTy = DL.getIntPtrType(M.getContext());
201
185 void ThreadSanitizer::initializeCallbacks(Module &M) {
202186 IRBuilder<> IRB(M.getContext());
203187 AttributeList Attr;
204188 Attr = Attr.addAttribute(M.getContext(), AttributeList::FunctionIndex,
212196 IRB.getVoidTy());
213197 TsanIgnoreEnd =
214198 M.getOrInsertFunction("__tsan_ignore_thread_end", Attr, IRB.getVoidTy());
215 IntegerType *OrdTy = IRB.getInt32Ty();
199 OrdTy = IRB.getInt32Ty();
216200 for (size_t i = 0; i < kNumberOfAccessSizes; ++i) {
217201 const unsigned ByteSize = 1U << i;
218202 const unsigned BitSize = ByteSize * 8;
293277 MemsetFn =
294278 M.getOrInsertFunction("memset", Attr, IRB.getInt8PtrTy(),
295279 IRB.getInt8PtrTy(), IRB.getInt32Ty(), IntptrTy);
280 }
281
282 ThreadSanitizer::ThreadSanitizer(Module &M) {
283 const DataLayout &DL = M.getDataLayout();
284 IntptrTy = DL.getIntPtrType(M.getContext());
285 std::tie(TsanCtorFunction, std::ignore) =
286 getOrCreateSanitizerCtorAndInitFunctions(
287 M, kTsanModuleCtorName, kTsanInitName, /*InitArgTypes=*/{},
288 /*InitArgs=*/{},
289 // This callback is invoked when the functions are created the first
290 // time. Hook them into the global ctors list in that case:
291 [&](Function *Ctor, FunctionCallee) {
292 appendToGlobalCtors(M, Ctor, 0);
293 });
296294 }
297295
298296 static bool isVtableAccess(Instruction *I) {
437435 const TargetLibraryInfo &TLI) {
438436 // This is required to prevent instrumenting call to __tsan_init from within
439437 // the module constructor.
440 if (F.getName() == kTsanModuleCtorName)
438 if (&F == TsanCtorFunction)
441439 return false;
442 initialize(*F.getParent());
440 initializeCallbacks(*F.getParent());
443441 SmallVector AllLoadsAndStores;
444442 SmallVector LocalLoadsAndStores;
445443 SmallVector AtomicAccesses;
None ; RUN: opt < %s -msan-check-access-address=0 -S -passes='module(msan-module),function(msan)' 2>&1 | FileCheck -allow-deprecated-dag-overlap %s
1 ; RUN: opt < %s --passes='module(msan-module),function(msan)' -msan-check-access-address=0 -S | FileCheck -allow-deprecated-dag-overlap %s
2 ; RUN: opt < %s -msan-check-access-address=0 -msan-track-origins=1 -S -passes='module(msan-module),function(msan)' 2>&1 | \
3 ; RUN: FileCheck -allow-deprecated-dag-overlap -check-prefixes=CHECK,CHECK-ORIGINS %s
4 ; RUN: opt < %s -passes='module(msan-module),function(msan)' -msan-check-access-address=0 -msan-track-origins=1 -S | \
5 ; RUN: FileCheck -allow-deprecated-dag-overlap -check-prefixes=CHECK,CHECK-ORIGINS %s
0 ; RUN: opt < %s -msan-check-access-address=0 -S -passes=msan 2>&1 | FileCheck \
1 ; RUN: -allow-deprecated-dag-overlap %s
2 ; RUN: opt < %s -msan -msan-check-access-address=0 -S | FileCheck -allow-deprecated-dag-overlap %s
3 ; RUN: opt < %s -msan-check-access-address=0 -msan-track-origins=1 -S \
4 ; RUN: -passes=msan 2>&1 | FileCheck -allow-deprecated-dag-overlap \
5 ; RUN: -check-prefix=CHECK -check-prefix=CHECK-ORIGINS %s
6 ; RUN: opt < %s -msan -msan-check-access-address=0 -msan-track-origins=1 -S | FileCheck -allow-deprecated-dag-overlap -check-prefix=CHECK -check-prefix=CHECK-ORIGINS %s
67
78 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-S128"
89 target triple = "x86_64-unknown-linux-gnu"
0 ; RUN: opt < %s -tsan -S | FileCheck %s
1 ; RUN: opt < %s -passes='function(tsan),module(tsan-module)' -S | FileCheck %s
1 ; RUN: opt < %s -passes=tsan -S | FileCheck %s
22
33 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"
44 target triple = "x86_64-unknown-linux-gnu"