Skip to content

Commit

Permalink
TSan: Use createSanitizerCtor to create ctor, and call __tsan_init
Browse files Browse the repository at this point in the history
Reviewers: kcc, dvyukov

Subscribers: llvm-commits

Differential Revision: http://reviews.llvm.org/D8779

llvm-svn: 236778
  • Loading branch information
ipazarbasi committed May 7, 2015
1 parent 09c3709 commit 2d4ae9f
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 7 deletions.
19 changes: 13 additions & 6 deletions llvm/lib/Transforms/Instrumentation/ThreadSanitizer.cpp
Expand Up @@ -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.
Expand Down Expand Up @@ -113,6 +116,7 @@ struct ThreadSanitizer : public FunctionPass {
Function *TsanVptrUpdate;
Function *TsanVptrLoad;
Function *MemmoveFn, *MemcpyFn, *MemsetFn;
Function *TsanCtorFunction;
};
} // namespace

Expand Down Expand Up @@ -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<Function>(TsanInit), 0);
appendToGlobalCtors(M, TsanCtorFunction, 0);

return true;
}
Expand Down Expand Up @@ -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<Instruction*, 8> RetVec;
SmallVector<Instruction*, 8> AllLoadsAndStores;
Expand Down
5 changes: 4 additions & 1 deletion llvm/test/Instrumentation/ThreadSanitizer/tsan_basic.ll
Expand Up @@ -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)
Expand Down Expand Up @@ -53,3 +53,6 @@ entry:
; CHECK: call i8* @memset
; CHECK: ret void
}

; CHECK: define internal void @tsan.module_ctor()
; CHECK: call void @__tsan_init()

0 comments on commit 2d4ae9f

Please sign in to comment.