mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-04-02 15:51:54 +00:00
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 llvm-svn: 374503
This commit is contained in:
parent
43c5f06ce2
commit
390cb2cadd
@ -40,7 +40,6 @@ struct MemorySanitizerPass : public PassInfoMixin<MemorySanitizerPass> {
|
|||||||
MemorySanitizerPass(MemorySanitizerOptions Options) : Options(Options) {}
|
MemorySanitizerPass(MemorySanitizerOptions Options) : Options(Options) {}
|
||||||
|
|
||||||
PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM);
|
PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM);
|
||||||
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
MemorySanitizerOptions Options;
|
MemorySanitizerOptions Options;
|
||||||
|
@ -27,8 +27,6 @@ FunctionPass *createThreadSanitizerLegacyPassPass();
|
|||||||
/// yet, the pass inserts the declarations. Otherwise the existing globals are
|
/// yet, the pass inserts the declarations. Otherwise the existing globals are
|
||||||
struct ThreadSanitizerPass : public PassInfoMixin<ThreadSanitizerPass> {
|
struct ThreadSanitizerPass : public PassInfoMixin<ThreadSanitizerPass> {
|
||||||
PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM);
|
PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM);
|
||||||
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace llvm
|
} // namespace llvm
|
||||||
#endif /* LLVM_TRANSFORMS_INSTRUMENTATION_THREADSANITIZER_H */
|
#endif /* LLVM_TRANSFORMS_INSTRUMENTATION_THREADSANITIZER_H */
|
||||||
|
@ -86,8 +86,6 @@ MODULE_PASS("synthetic-counts-propagation", SyntheticCountsPropagation())
|
|||||||
MODULE_PASS("wholeprogramdevirt", WholeProgramDevirtPass(nullptr, nullptr))
|
MODULE_PASS("wholeprogramdevirt", WholeProgramDevirtPass(nullptr, nullptr))
|
||||||
MODULE_PASS("verify", VerifierPass())
|
MODULE_PASS("verify", VerifierPass())
|
||||||
MODULE_PASS("asan-module", ModuleAddressSanitizerPass(/*CompileKernel=*/false, false, true, false))
|
MODULE_PASS("asan-module", ModuleAddressSanitizerPass(/*CompileKernel=*/false, false, true, false))
|
||||||
MODULE_PASS("msan-module", MemorySanitizerPass({}))
|
|
||||||
MODULE_PASS("tsan-module", ThreadSanitizerPass())
|
|
||||||
MODULE_PASS("kasan-module", ModuleAddressSanitizerPass(/*CompileKernel=*/true, false, true, false))
|
MODULE_PASS("kasan-module", ModuleAddressSanitizerPass(/*CompileKernel=*/true, false, true, false))
|
||||||
MODULE_PASS("sancov-module", ModuleSanitizerCoveragePass())
|
MODULE_PASS("sancov-module", ModuleSanitizerCoveragePass())
|
||||||
MODULE_PASS("poison-checking", PoisonCheckingPass())
|
MODULE_PASS("poison-checking", PoisonCheckingPass())
|
||||||
|
@ -587,25 +587,9 @@ private:
|
|||||||
|
|
||||||
/// An empty volatile inline asm that prevents callback merge.
|
/// An empty volatile inline asm that prevents callback merge.
|
||||||
InlineAsm *EmptyAsm;
|
InlineAsm *EmptyAsm;
|
||||||
};
|
|
||||||
|
|
||||||
void insertModuleCtor(Module &M) {
|
Function *MsanCtorFunction;
|
||||||
getOrCreateSanitizerCtorAndInitFunctions(
|
};
|
||||||
M, kMsanModuleCtorName, kMsanInitName,
|
|
||||||
/*InitArgTypes=*/{},
|
|
||||||
/*InitArgs=*/{},
|
|
||||||
// This callback is invoked when the functions are created the first
|
|
||||||
// time. Hook them into the global ctors list in that case:
|
|
||||||
[&](Function *Ctor, FunctionCallee) {
|
|
||||||
if (!ClWithComdat) {
|
|
||||||
appendToGlobalCtors(M, Ctor, 0);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Comdat *MsanCtorComdat = M.getOrInsertComdat(kMsanModuleCtorName);
|
|
||||||
Ctor->setComdat(MsanCtorComdat);
|
|
||||||
appendToGlobalCtors(M, Ctor, 0, Ctor);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A legacy function pass for msan instrumentation.
|
/// A legacy function pass for msan instrumentation.
|
||||||
///
|
///
|
||||||
@ -651,14 +635,6 @@ PreservedAnalyses MemorySanitizerPass::run(Function &F,
|
|||||||
return PreservedAnalyses::all();
|
return PreservedAnalyses::all();
|
||||||
}
|
}
|
||||||
|
|
||||||
PreservedAnalyses MemorySanitizerPass::run(Module &M,
|
|
||||||
ModuleAnalysisManager &AM) {
|
|
||||||
if (Options.Kernel)
|
|
||||||
return PreservedAnalyses::all();
|
|
||||||
insertModuleCtor(M);
|
|
||||||
return PreservedAnalyses::none();
|
|
||||||
}
|
|
||||||
|
|
||||||
char MemorySanitizerLegacyPass::ID = 0;
|
char MemorySanitizerLegacyPass::ID = 0;
|
||||||
|
|
||||||
INITIALIZE_PASS_BEGIN(MemorySanitizerLegacyPass, "msan",
|
INITIALIZE_PASS_BEGIN(MemorySanitizerLegacyPass, "msan",
|
||||||
@ -944,6 +920,23 @@ void MemorySanitizer::initializeModule(Module &M) {
|
|||||||
OriginStoreWeights = MDBuilder(*C).createBranchWeights(1, 1000);
|
OriginStoreWeights = MDBuilder(*C).createBranchWeights(1, 1000);
|
||||||
|
|
||||||
if (!CompileKernel) {
|
if (!CompileKernel) {
|
||||||
|
std::tie(MsanCtorFunction, std::ignore) =
|
||||||
|
getOrCreateSanitizerCtorAndInitFunctions(
|
||||||
|
M, kMsanModuleCtorName, kMsanInitName,
|
||||||
|
/*InitArgTypes=*/{},
|
||||||
|
/*InitArgs=*/{},
|
||||||
|
// This callback is invoked when the functions are created the first
|
||||||
|
// time. Hook them into the global ctors list in that case:
|
||||||
|
[&](Function *Ctor, FunctionCallee) {
|
||||||
|
if (!ClWithComdat) {
|
||||||
|
appendToGlobalCtors(M, Ctor, 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Comdat *MsanCtorComdat = M.getOrInsertComdat(kMsanModuleCtorName);
|
||||||
|
Ctor->setComdat(MsanCtorComdat);
|
||||||
|
appendToGlobalCtors(M, Ctor, 0, Ctor);
|
||||||
|
});
|
||||||
|
|
||||||
if (TrackOrigins)
|
if (TrackOrigins)
|
||||||
M.getOrInsertGlobal("__msan_track_origins", IRB.getInt32Ty(), [&] {
|
M.getOrInsertGlobal("__msan_track_origins", IRB.getInt32Ty(), [&] {
|
||||||
return new GlobalVariable(
|
return new GlobalVariable(
|
||||||
@ -961,8 +954,6 @@ void MemorySanitizer::initializeModule(Module &M) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool MemorySanitizerLegacyPass::doInitialization(Module &M) {
|
bool MemorySanitizerLegacyPass::doInitialization(Module &M) {
|
||||||
if (!Options.Kernel)
|
|
||||||
insertModuleCtor(M);
|
|
||||||
MSan.emplace(M, Options);
|
MSan.emplace(M, Options);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -4587,9 +4578,8 @@ static VarArgHelper *CreateVarArgHelper(Function &Func, MemorySanitizer &Msan,
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool MemorySanitizer::sanitizeFunction(Function &F, TargetLibraryInfo &TLI) {
|
bool MemorySanitizer::sanitizeFunction(Function &F, TargetLibraryInfo &TLI) {
|
||||||
if (!CompileKernel && F.getName() == kMsanModuleCtorName)
|
if (!CompileKernel && (&F == MsanCtorFunction))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
MemorySanitizerVisitor Visitor(F, *this, TLI);
|
MemorySanitizerVisitor Visitor(F, *this, TLI);
|
||||||
|
|
||||||
// Clear out readonly/readnone attributes.
|
// Clear out readonly/readnone attributes.
|
||||||
|
@ -92,10 +92,11 @@ namespace {
|
|||||||
/// ensures the __tsan_init function is in the list of global constructors for
|
/// ensures the __tsan_init function is in the list of global constructors for
|
||||||
/// the module.
|
/// the module.
|
||||||
struct ThreadSanitizer {
|
struct ThreadSanitizer {
|
||||||
|
ThreadSanitizer(Module &M);
|
||||||
bool sanitizeFunction(Function &F, const TargetLibraryInfo &TLI);
|
bool sanitizeFunction(Function &F, const TargetLibraryInfo &TLI);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void initialize(Module &M);
|
void initializeCallbacks(Module &M);
|
||||||
bool instrumentLoadOrStore(Instruction *I, const DataLayout &DL);
|
bool instrumentLoadOrStore(Instruction *I, const DataLayout &DL);
|
||||||
bool instrumentAtomic(Instruction *I, const DataLayout &DL);
|
bool instrumentAtomic(Instruction *I, const DataLayout &DL);
|
||||||
bool instrumentMemIntrinsic(Instruction *I);
|
bool instrumentMemIntrinsic(Instruction *I);
|
||||||
@ -107,6 +108,8 @@ private:
|
|||||||
void InsertRuntimeIgnores(Function &F);
|
void InsertRuntimeIgnores(Function &F);
|
||||||
|
|
||||||
Type *IntptrTy;
|
Type *IntptrTy;
|
||||||
|
IntegerType *OrdTy;
|
||||||
|
// Callbacks to run-time library are computed in doInitialization.
|
||||||
FunctionCallee TsanFuncEntry;
|
FunctionCallee TsanFuncEntry;
|
||||||
FunctionCallee TsanFuncExit;
|
FunctionCallee TsanFuncExit;
|
||||||
FunctionCallee TsanIgnoreBegin;
|
FunctionCallee TsanIgnoreBegin;
|
||||||
@ -127,6 +130,7 @@ private:
|
|||||||
FunctionCallee TsanVptrUpdate;
|
FunctionCallee TsanVptrUpdate;
|
||||||
FunctionCallee TsanVptrLoad;
|
FunctionCallee TsanVptrLoad;
|
||||||
FunctionCallee MemmoveFn, MemcpyFn, MemsetFn;
|
FunctionCallee MemmoveFn, MemcpyFn, MemsetFn;
|
||||||
|
Function *TsanCtorFunction;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ThreadSanitizerLegacyPass : FunctionPass {
|
struct ThreadSanitizerLegacyPass : FunctionPass {
|
||||||
@ -139,32 +143,16 @@ struct ThreadSanitizerLegacyPass : FunctionPass {
|
|||||||
private:
|
private:
|
||||||
Optional<ThreadSanitizer> TSan;
|
Optional<ThreadSanitizer> TSan;
|
||||||
};
|
};
|
||||||
|
|
||||||
void insertModuleCtor(Module &M) {
|
|
||||||
getOrCreateSanitizerCtorAndInitFunctions(
|
|
||||||
M, kTsanModuleCtorName, kTsanInitName, /*InitArgTypes=*/{},
|
|
||||||
/*InitArgs=*/{},
|
|
||||||
// This callback is invoked when the functions are created the first
|
|
||||||
// time. Hook them into the global ctors list in that case:
|
|
||||||
[&](Function *Ctor, FunctionCallee) { appendToGlobalCtors(M, Ctor, 0); });
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
PreservedAnalyses ThreadSanitizerPass::run(Function &F,
|
PreservedAnalyses ThreadSanitizerPass::run(Function &F,
|
||||||
FunctionAnalysisManager &FAM) {
|
FunctionAnalysisManager &FAM) {
|
||||||
ThreadSanitizer TSan;
|
ThreadSanitizer TSan(*F.getParent());
|
||||||
if (TSan.sanitizeFunction(F, FAM.getResult<TargetLibraryAnalysis>(F)))
|
if (TSan.sanitizeFunction(F, FAM.getResult<TargetLibraryAnalysis>(F)))
|
||||||
return PreservedAnalyses::none();
|
return PreservedAnalyses::none();
|
||||||
return PreservedAnalyses::all();
|
return PreservedAnalyses::all();
|
||||||
}
|
}
|
||||||
|
|
||||||
PreservedAnalyses ThreadSanitizerPass::run(Module &M,
|
|
||||||
ModuleAnalysisManager &MAM) {
|
|
||||||
insertModuleCtor(M);
|
|
||||||
return PreservedAnalyses::none();
|
|
||||||
}
|
|
||||||
|
|
||||||
char ThreadSanitizerLegacyPass::ID = 0;
|
char ThreadSanitizerLegacyPass::ID = 0;
|
||||||
INITIALIZE_PASS_BEGIN(ThreadSanitizerLegacyPass, "tsan",
|
INITIALIZE_PASS_BEGIN(ThreadSanitizerLegacyPass, "tsan",
|
||||||
"ThreadSanitizer: detects data races.", false, false)
|
"ThreadSanitizer: detects data races.", false, false)
|
||||||
@ -181,8 +169,7 @@ void ThreadSanitizerLegacyPass::getAnalysisUsage(AnalysisUsage &AU) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool ThreadSanitizerLegacyPass::doInitialization(Module &M) {
|
bool ThreadSanitizerLegacyPass::doInitialization(Module &M) {
|
||||||
insertModuleCtor(M);
|
TSan.emplace(M);
|
||||||
TSan.emplace();
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -196,10 +183,7 @@ FunctionPass *llvm::createThreadSanitizerLegacyPassPass() {
|
|||||||
return new ThreadSanitizerLegacyPass();
|
return new ThreadSanitizerLegacyPass();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ThreadSanitizer::initialize(Module &M) {
|
void ThreadSanitizer::initializeCallbacks(Module &M) {
|
||||||
const DataLayout &DL = M.getDataLayout();
|
|
||||||
IntptrTy = DL.getIntPtrType(M.getContext());
|
|
||||||
|
|
||||||
IRBuilder<> IRB(M.getContext());
|
IRBuilder<> IRB(M.getContext());
|
||||||
AttributeList Attr;
|
AttributeList Attr;
|
||||||
Attr = Attr.addAttribute(M.getContext(), AttributeList::FunctionIndex,
|
Attr = Attr.addAttribute(M.getContext(), AttributeList::FunctionIndex,
|
||||||
@ -213,7 +197,7 @@ void ThreadSanitizer::initialize(Module &M) {
|
|||||||
IRB.getVoidTy());
|
IRB.getVoidTy());
|
||||||
TsanIgnoreEnd =
|
TsanIgnoreEnd =
|
||||||
M.getOrInsertFunction("__tsan_ignore_thread_end", Attr, IRB.getVoidTy());
|
M.getOrInsertFunction("__tsan_ignore_thread_end", Attr, IRB.getVoidTy());
|
||||||
IntegerType *OrdTy = IRB.getInt32Ty();
|
OrdTy = IRB.getInt32Ty();
|
||||||
for (size_t i = 0; i < kNumberOfAccessSizes; ++i) {
|
for (size_t i = 0; i < kNumberOfAccessSizes; ++i) {
|
||||||
const unsigned ByteSize = 1U << i;
|
const unsigned ByteSize = 1U << i;
|
||||||
const unsigned BitSize = ByteSize * 8;
|
const unsigned BitSize = ByteSize * 8;
|
||||||
@ -296,6 +280,20 @@ void ThreadSanitizer::initialize(Module &M) {
|
|||||||
IRB.getInt8PtrTy(), IRB.getInt32Ty(), IntptrTy);
|
IRB.getInt8PtrTy(), IRB.getInt32Ty(), IntptrTy);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ThreadSanitizer::ThreadSanitizer(Module &M) {
|
||||||
|
const DataLayout &DL = M.getDataLayout();
|
||||||
|
IntptrTy = DL.getIntPtrType(M.getContext());
|
||||||
|
std::tie(TsanCtorFunction, std::ignore) =
|
||||||
|
getOrCreateSanitizerCtorAndInitFunctions(
|
||||||
|
M, kTsanModuleCtorName, kTsanInitName, /*InitArgTypes=*/{},
|
||||||
|
/*InitArgs=*/{},
|
||||||
|
// This callback is invoked when the functions are created the first
|
||||||
|
// time. Hook them into the global ctors list in that case:
|
||||||
|
[&](Function *Ctor, FunctionCallee) {
|
||||||
|
appendToGlobalCtors(M, Ctor, 0);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
static bool isVtableAccess(Instruction *I) {
|
static bool isVtableAccess(Instruction *I) {
|
||||||
if (MDNode *Tag = I->getMetadata(LLVMContext::MD_tbaa))
|
if (MDNode *Tag = I->getMetadata(LLVMContext::MD_tbaa))
|
||||||
return Tag->isTBAAVtableAccess();
|
return Tag->isTBAAVtableAccess();
|
||||||
@ -438,9 +436,9 @@ bool ThreadSanitizer::sanitizeFunction(Function &F,
|
|||||||
const TargetLibraryInfo &TLI) {
|
const TargetLibraryInfo &TLI) {
|
||||||
// This is required to prevent instrumenting call to __tsan_init from within
|
// This is required to prevent instrumenting call to __tsan_init from within
|
||||||
// the module constructor.
|
// the module constructor.
|
||||||
if (F.getName() == kTsanModuleCtorName)
|
if (&F == TsanCtorFunction)
|
||||||
return false;
|
return false;
|
||||||
initialize(*F.getParent());
|
initializeCallbacks(*F.getParent());
|
||||||
SmallVector<Instruction*, 8> AllLoadsAndStores;
|
SmallVector<Instruction*, 8> AllLoadsAndStores;
|
||||||
SmallVector<Instruction*, 8> LocalLoadsAndStores;
|
SmallVector<Instruction*, 8> LocalLoadsAndStores;
|
||||||
SmallVector<Instruction*, 8> AtomicAccesses;
|
SmallVector<Instruction*, 8> AtomicAccesses;
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
; RUN: opt < %s -msan-check-access-address=0 -S -passes='module(msan-module),function(msan)' 2>&1 | FileCheck -allow-deprecated-dag-overlap %s
|
; RUN: opt < %s -msan-check-access-address=0 -S -passes=msan 2>&1 | FileCheck \
|
||||||
; RUN: opt < %s --passes='module(msan-module),function(msan)' -msan-check-access-address=0 -S | FileCheck -allow-deprecated-dag-overlap %s
|
; RUN: -allow-deprecated-dag-overlap %s
|
||||||
; RUN: opt < %s -msan-check-access-address=0 -msan-track-origins=1 -S -passes='module(msan-module),function(msan)' 2>&1 | \
|
; RUN: opt < %s -msan -msan-check-access-address=0 -S | FileCheck -allow-deprecated-dag-overlap %s
|
||||||
; RUN: FileCheck -allow-deprecated-dag-overlap -check-prefixes=CHECK,CHECK-ORIGINS %s
|
; RUN: opt < %s -msan-check-access-address=0 -msan-track-origins=1 -S \
|
||||||
; RUN: opt < %s -passes='module(msan-module),function(msan)' -msan-check-access-address=0 -msan-track-origins=1 -S | \
|
; RUN: -passes=msan 2>&1 | FileCheck -allow-deprecated-dag-overlap \
|
||||||
; RUN: FileCheck -allow-deprecated-dag-overlap -check-prefixes=CHECK,CHECK-ORIGINS %s
|
; RUN: -check-prefix=CHECK -check-prefix=CHECK-ORIGINS %s
|
||||||
|
; 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
|
||||||
|
|
||||||
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"
|
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"
|
||||||
target triple = "x86_64-unknown-linux-gnu"
|
target triple = "x86_64-unknown-linux-gnu"
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
; RUN: opt < %s -tsan -S | FileCheck %s
|
; RUN: opt < %s -tsan -S | FileCheck %s
|
||||||
; RUN: opt < %s -passes='function(tsan),module(tsan-module)' -S | FileCheck %s
|
; RUN: opt < %s -passes=tsan -S | FileCheck %s
|
||||||
|
|
||||||
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"
|
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"
|
||||||
target triple = "x86_64-unknown-linux-gnu"
|
target triple = "x86_64-unknown-linux-gnu"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user