From 2bdae13effc91ded81cf844306d89e44d838249f Mon Sep 17 00:00:00 2001 From: Ismail Pazarbasi Date: Thu, 7 May 2015 21:41:23 +0000 Subject: [PATCH] TSan: Use `createSanitizerCtor` to create ctor, and call `__tsan_init` Reviewers: kcc, dvyukov Subscribers: llvm-commits Differential Revision: http://reviews.llvm.org/D8779 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@236778 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../Instrumentation/ThreadSanitizer.cpp | 19 +++++++++++++------ .../ThreadSanitizer/tsan_basic.ll | 5 ++++- 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/lib/Transforms/Instrumentation/ThreadSanitizer.cpp b/lib/Transforms/Instrumentation/ThreadSanitizer.cpp index aa8ee5aab7d..b23dacc5638 100644 --- a/lib/Transforms/Instrumentation/ThreadSanitizer.cpp +++ b/lib/Transforms/Instrumentation/ThreadSanitizer.cpp @@ -72,6 +72,9 @@ STATISTIC(NumOmittedReadsFromConstantGlobals, STATISTIC(NumOmittedReadsFromVtable, "Number of vtable reads"); STATISTIC(NumOmittedNonCaptured, "Number of accesses ignored due to capturing"); +static const char *const kTsanModuleCtorName = "tsan.module_ctor"; +static const char *const kTsanInitName = "__tsan_init"; + namespace { /// ThreadSanitizer: instrument the code in module to find races. @@ -113,6 +116,7 @@ struct ThreadSanitizer : public FunctionPass { Function *TsanVptrUpdate; Function *TsanVptrLoad; Function *MemmoveFn, *MemcpyFn, *MemsetFn; + Function *TsanCtorFunction; }; } // namespace @@ -225,13 +229,12 @@ void ThreadSanitizer::initializeCallbacks(Module &M) { bool ThreadSanitizer::doInitialization(Module &M) { const DataLayout &DL = M.getDataLayout(); + IntptrTy = DL.getIntPtrType(M.getContext()); + std::tie(TsanCtorFunction, std::ignore) = createSanitizerCtorAndInitFunctions( + M, kTsanModuleCtorName, kTsanInitName, /*InitArgTypes=*/{}, + /*InitArgs=*/{}); - // Always insert a call to __tsan_init into the module's CTORs. - IRBuilder<> IRB(M.getContext()); - IntptrTy = IRB.getIntPtrTy(DL); - Value *TsanInit = M.getOrInsertFunction("__tsan_init", - IRB.getVoidTy(), nullptr); - appendToGlobalCtors(M, cast(TsanInit), 0); + appendToGlobalCtors(M, TsanCtorFunction, 0); return true; } @@ -329,6 +332,10 @@ static bool isAtomic(Instruction *I) { } bool ThreadSanitizer::runOnFunction(Function &F) { + // This is required to prevent instrumenting call to __tsan_init from within + // the module constructor. + if (&F == TsanCtorFunction) + return false; initializeCallbacks(*F.getParent()); SmallVector RetVec; SmallVector AllLoadsAndStores; diff --git a/test/Instrumentation/ThreadSanitizer/tsan_basic.ll b/test/Instrumentation/ThreadSanitizer/tsan_basic.ll index 22582ebda73..7e049c548f2 100644 --- a/test/Instrumentation/ThreadSanitizer/tsan_basic.ll +++ b/test/Instrumentation/ThreadSanitizer/tsan_basic.ll @@ -9,7 +9,7 @@ entry: ret i32 %tmp1 } -; CHECK: @llvm.global_ctors = {{.*}}@__tsan_init +; CHECK: @llvm.global_ctors = {{.*}}@tsan.module_ctor ; CHECK: define i32 @read_4_bytes(i32* %a) ; CHECK: call void @__tsan_func_entry(i8* %0) @@ -53,3 +53,6 @@ entry: ; CHECK: call i8* @memset ; CHECK: ret void } + +; CHECK: define internal void @tsan.module_ctor() +; CHECK: call void @__tsan_init()