Move checkInterfaceFunction to ModuleUtils

Summary:
Instead of making a local copy of `checkInterfaceFunction` for each
sanitizer, move the function in a common place.

Reviewers: kcc, samsonov

Subscribers: llvm-commits

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

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@234220 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Ismail Pazarbasi 2015-04-06 21:09:08 +00:00
parent af1023588e
commit aa5880df12
5 changed files with 83 additions and 90 deletions

View File

@ -20,6 +20,7 @@ class Module;
class Function; class Function;
class GlobalValue; class GlobalValue;
class GlobalVariable; class GlobalVariable;
class Constant;
template <class PtrType> class SmallPtrSetImpl; template <class PtrType> class SmallPtrSetImpl;
/// Append F to the list of global ctors of module M with the given Priority. /// Append F to the list of global ctors of module M with the given Priority.
@ -36,6 +37,12 @@ void appendToGlobalDtors(Module &M, Function *F, int Priority);
GlobalVariable *collectUsedGlobalVariables(Module &M, GlobalVariable *collectUsedGlobalVariables(Module &M,
SmallPtrSetImpl<GlobalValue *> &Set, SmallPtrSetImpl<GlobalValue *> &Set,
bool CompilerUsed); bool CompilerUsed);
// Validate the result of Module::getOrInsertFunction called for an interface
// function of given sanitizer. If the instrumented module defines a function
// with the same name, their prototypes must match, otherwise
// getOrInsertFunction returns a bitcast.
Function *checkSanitizerInterfaceFunction(Constant *FuncOrBitcast);
} // End llvm namespace } // End llvm namespace
#endif // LLVM_TRANSFORMS_UTILS_MODULEUTILS_H #endif // LLVM_TRANSFORMS_UTILS_MODULEUTILS_H

View File

@ -968,18 +968,6 @@ void AddressSanitizer::instrumentMop(ObjectSizeOffsetVisitor &ObjSizeVis,
UseCalls, Exp); UseCalls, Exp);
} }
// Validate the result of Module::getOrInsertFunction called for an interface
// function of AddressSanitizer. If the instrumented module defines a function
// with the same name, their prototypes must match, otherwise
// getOrInsertFunction returns a bitcast.
static Function *checkInterfaceFunction(Constant *FuncOrBitcast) {
if (isa<Function>(FuncOrBitcast)) return cast<Function>(FuncOrBitcast);
FuncOrBitcast->dump();
report_fatal_error(
"trying to redefine an AddressSanitizer "
"interface function");
}
Instruction *AddressSanitizer::generateCrashCode(Instruction *InsertBefore, Instruction *AddressSanitizer::generateCrashCode(Instruction *InsertBefore,
Value *Addr, bool IsWrite, Value *Addr, bool IsWrite,
size_t AccessSizeIndex, size_t AccessSizeIndex,
@ -1228,17 +1216,17 @@ bool AddressSanitizerModule::ShouldInstrumentGlobal(GlobalVariable *G) {
void AddressSanitizerModule::initializeCallbacks(Module &M) { void AddressSanitizerModule::initializeCallbacks(Module &M) {
IRBuilder<> IRB(*C); IRBuilder<> IRB(*C);
// Declare our poisoning and unpoisoning functions. // Declare our poisoning and unpoisoning functions.
AsanPoisonGlobals = checkInterfaceFunction(M.getOrInsertFunction( AsanPoisonGlobals = checkSanitizerInterfaceFunction(M.getOrInsertFunction(
kAsanPoisonGlobalsName, IRB.getVoidTy(), IntptrTy, nullptr)); kAsanPoisonGlobalsName, IRB.getVoidTy(), IntptrTy, nullptr));
AsanPoisonGlobals->setLinkage(Function::ExternalLinkage); AsanPoisonGlobals->setLinkage(Function::ExternalLinkage);
AsanUnpoisonGlobals = checkInterfaceFunction(M.getOrInsertFunction( AsanUnpoisonGlobals = checkSanitizerInterfaceFunction(M.getOrInsertFunction(
kAsanUnpoisonGlobalsName, IRB.getVoidTy(), nullptr)); kAsanUnpoisonGlobalsName, IRB.getVoidTy(), nullptr));
AsanUnpoisonGlobals->setLinkage(Function::ExternalLinkage); AsanUnpoisonGlobals->setLinkage(Function::ExternalLinkage);
// Declare functions that register/unregister globals. // Declare functions that register/unregister globals.
AsanRegisterGlobals = checkInterfaceFunction(M.getOrInsertFunction( AsanRegisterGlobals = checkSanitizerInterfaceFunction(M.getOrInsertFunction(
kAsanRegisterGlobalsName, IRB.getVoidTy(), IntptrTy, IntptrTy, nullptr)); kAsanRegisterGlobalsName, IRB.getVoidTy(), IntptrTy, IntptrTy, nullptr));
AsanRegisterGlobals->setLinkage(Function::ExternalLinkage); AsanRegisterGlobals->setLinkage(Function::ExternalLinkage);
AsanUnregisterGlobals = checkInterfaceFunction( AsanUnregisterGlobals = checkSanitizerInterfaceFunction(
M.getOrInsertFunction(kAsanUnregisterGlobalsName, IRB.getVoidTy(), M.getOrInsertFunction(kAsanUnregisterGlobalsName, IRB.getVoidTy(),
IntptrTy, IntptrTy, nullptr)); IntptrTy, IntptrTy, nullptr));
AsanUnregisterGlobals->setLinkage(Function::ExternalLinkage); AsanUnregisterGlobals->setLinkage(Function::ExternalLinkage);
@ -1408,44 +1396,44 @@ void AddressSanitizer::initializeCallbacks(Module &M) {
const std::string ExpStr = Exp ? "exp_" : ""; const std::string ExpStr = Exp ? "exp_" : "";
const Type *ExpType = Exp ? Type::getInt32Ty(*C) : nullptr; const Type *ExpType = Exp ? Type::getInt32Ty(*C) : nullptr;
AsanErrorCallbackSized[AccessIsWrite][Exp] = AsanErrorCallbackSized[AccessIsWrite][Exp] =
checkInterfaceFunction(M.getOrInsertFunction( checkSanitizerInterfaceFunction(M.getOrInsertFunction(
kAsanReportErrorTemplate + ExpStr + TypeStr + "_n", kAsanReportErrorTemplate + ExpStr + TypeStr + "_n",
IRB.getVoidTy(), IntptrTy, IntptrTy, ExpType, nullptr)); IRB.getVoidTy(), IntptrTy, IntptrTy, ExpType, nullptr));
AsanMemoryAccessCallbackSized[AccessIsWrite][Exp] = AsanMemoryAccessCallbackSized[AccessIsWrite][Exp] =
checkInterfaceFunction(M.getOrInsertFunction( checkSanitizerInterfaceFunction(M.getOrInsertFunction(
ClMemoryAccessCallbackPrefix + ExpStr + TypeStr + "N", ClMemoryAccessCallbackPrefix + ExpStr + TypeStr + "N",
IRB.getVoidTy(), IntptrTy, IntptrTy, ExpType, nullptr)); IRB.getVoidTy(), IntptrTy, IntptrTy, ExpType, nullptr));
for (size_t AccessSizeIndex = 0; AccessSizeIndex < kNumberOfAccessSizes; for (size_t AccessSizeIndex = 0; AccessSizeIndex < kNumberOfAccessSizes;
AccessSizeIndex++) { AccessSizeIndex++) {
const std::string Suffix = TypeStr + itostr(1 << AccessSizeIndex); const std::string Suffix = TypeStr + itostr(1 << AccessSizeIndex);
AsanErrorCallback[AccessIsWrite][Exp][AccessSizeIndex] = AsanErrorCallback[AccessIsWrite][Exp][AccessSizeIndex] =
checkInterfaceFunction(M.getOrInsertFunction( checkSanitizerInterfaceFunction(M.getOrInsertFunction(
kAsanReportErrorTemplate + ExpStr + Suffix, IRB.getVoidTy(), kAsanReportErrorTemplate + ExpStr + Suffix, IRB.getVoidTy(),
IntptrTy, ExpType, nullptr)); IntptrTy, ExpType, nullptr));
AsanMemoryAccessCallback[AccessIsWrite][Exp][AccessSizeIndex] = AsanMemoryAccessCallback[AccessIsWrite][Exp][AccessSizeIndex] =
checkInterfaceFunction(M.getOrInsertFunction( checkSanitizerInterfaceFunction(M.getOrInsertFunction(
ClMemoryAccessCallbackPrefix + ExpStr + Suffix, IRB.getVoidTy(), ClMemoryAccessCallbackPrefix + ExpStr + Suffix, IRB.getVoidTy(),
IntptrTy, ExpType, nullptr)); IntptrTy, ExpType, nullptr));
} }
} }
} }
AsanMemmove = checkInterfaceFunction(M.getOrInsertFunction( AsanMemmove = checkSanitizerInterfaceFunction(M.getOrInsertFunction(
ClMemoryAccessCallbackPrefix + "memmove", IRB.getInt8PtrTy(), ClMemoryAccessCallbackPrefix + "memmove", IRB.getInt8PtrTy(),
IRB.getInt8PtrTy(), IRB.getInt8PtrTy(), IntptrTy, nullptr)); IRB.getInt8PtrTy(), IRB.getInt8PtrTy(), IntptrTy, nullptr));
AsanMemcpy = checkInterfaceFunction(M.getOrInsertFunction( AsanMemcpy = checkSanitizerInterfaceFunction(M.getOrInsertFunction(
ClMemoryAccessCallbackPrefix + "memcpy", IRB.getInt8PtrTy(), ClMemoryAccessCallbackPrefix + "memcpy", IRB.getInt8PtrTy(),
IRB.getInt8PtrTy(), IRB.getInt8PtrTy(), IntptrTy, nullptr)); IRB.getInt8PtrTy(), IRB.getInt8PtrTy(), IntptrTy, nullptr));
AsanMemset = checkInterfaceFunction(M.getOrInsertFunction( AsanMemset = checkSanitizerInterfaceFunction(M.getOrInsertFunction(
ClMemoryAccessCallbackPrefix + "memset", IRB.getInt8PtrTy(), ClMemoryAccessCallbackPrefix + "memset", IRB.getInt8PtrTy(),
IRB.getInt8PtrTy(), IRB.getInt32Ty(), IntptrTy, nullptr)); IRB.getInt8PtrTy(), IRB.getInt32Ty(), IntptrTy, nullptr));
AsanHandleNoReturnFunc = checkInterfaceFunction( AsanHandleNoReturnFunc = checkSanitizerInterfaceFunction(
M.getOrInsertFunction(kAsanHandleNoReturnName, IRB.getVoidTy(), nullptr)); M.getOrInsertFunction(kAsanHandleNoReturnName, IRB.getVoidTy(), nullptr));
AsanPtrCmpFunction = checkInterfaceFunction(M.getOrInsertFunction( AsanPtrCmpFunction = checkSanitizerInterfaceFunction(M.getOrInsertFunction(
kAsanPtrCmp, IRB.getVoidTy(), IntptrTy, IntptrTy, nullptr)); kAsanPtrCmp, IRB.getVoidTy(), IntptrTy, IntptrTy, nullptr));
AsanPtrSubFunction = checkInterfaceFunction(M.getOrInsertFunction( AsanPtrSubFunction = checkSanitizerInterfaceFunction(M.getOrInsertFunction(
kAsanPtrSub, IRB.getVoidTy(), IntptrTy, IntptrTy, nullptr)); kAsanPtrSub, IRB.getVoidTy(), IntptrTy, IntptrTy, nullptr));
// We insert an empty inline asm after __asan_report* to avoid callback merge. // We insert an empty inline asm after __asan_report* to avoid callback merge.
EmptyAsm = InlineAsm::get(FunctionType::get(IRB.getVoidTy(), false), EmptyAsm = InlineAsm::get(FunctionType::get(IRB.getVoidTy(), false),
@ -1470,7 +1458,7 @@ bool AddressSanitizer::doInitialization(Module &M) {
BasicBlock *AsanCtorBB = BasicBlock::Create(*C, "", AsanCtorFunction); BasicBlock *AsanCtorBB = BasicBlock::Create(*C, "", AsanCtorFunction);
// call __asan_init in the module ctor. // call __asan_init in the module ctor.
IRBuilder<> IRB(ReturnInst::Create(*C, AsanCtorBB)); IRBuilder<> IRB(ReturnInst::Create(*C, AsanCtorBB));
AsanInitFunction = checkInterfaceFunction( AsanInitFunction = checkSanitizerInterfaceFunction(
M.getOrInsertFunction(kAsanInitName, IRB.getVoidTy(), nullptr)); M.getOrInsertFunction(kAsanInitName, IRB.getVoidTy(), nullptr));
AsanInitFunction->setLinkage(Function::ExternalLinkage); AsanInitFunction->setLinkage(Function::ExternalLinkage);
IRB.CreateCall(AsanInitFunction); IRB.CreateCall(AsanInitFunction);
@ -1622,16 +1610,17 @@ void FunctionStackPoisoner::initializeCallbacks(Module &M) {
IRBuilder<> IRB(*C); IRBuilder<> IRB(*C);
for (int i = 0; i <= kMaxAsanStackMallocSizeClass; i++) { for (int i = 0; i <= kMaxAsanStackMallocSizeClass; i++) {
std::string Suffix = itostr(i); std::string Suffix = itostr(i);
AsanStackMallocFunc[i] = checkInterfaceFunction(M.getOrInsertFunction( AsanStackMallocFunc[i] = checkSanitizerInterfaceFunction(
kAsanStackMallocNameTemplate + Suffix, IntptrTy, IntptrTy, nullptr)); M.getOrInsertFunction(kAsanStackMallocNameTemplate + Suffix, IntptrTy,
AsanStackFreeFunc[i] = checkInterfaceFunction( IntptrTy, nullptr));
AsanStackFreeFunc[i] = checkSanitizerInterfaceFunction(
M.getOrInsertFunction(kAsanStackFreeNameTemplate + Suffix, M.getOrInsertFunction(kAsanStackFreeNameTemplate + Suffix,
IRB.getVoidTy(), IntptrTy, IntptrTy, nullptr)); IRB.getVoidTy(), IntptrTy, IntptrTy, nullptr));
} }
AsanPoisonStackMemoryFunc = checkInterfaceFunction( AsanPoisonStackMemoryFunc = checkSanitizerInterfaceFunction(
M.getOrInsertFunction(kAsanPoisonStackMemoryName, IRB.getVoidTy(), M.getOrInsertFunction(kAsanPoisonStackMemoryName, IRB.getVoidTy(),
IntptrTy, IntptrTy, nullptr)); IntptrTy, IntptrTy, nullptr));
AsanUnpoisonStackMemoryFunc = checkInterfaceFunction( AsanUnpoisonStackMemoryFunc = checkSanitizerInterfaceFunction(
M.getOrInsertFunction(kAsanUnpoisonStackMemoryName, IRB.getVoidTy(), M.getOrInsertFunction(kAsanUnpoisonStackMemoryName, IRB.getVoidTy(),
IntptrTy, IntptrTy, nullptr)); IntptrTy, IntptrTy, nullptr));
} }

View File

@ -140,16 +140,6 @@ class SanitizerCoverageModule : public ModulePass {
} // namespace } // namespace
static Function *checkInterfaceFunction(Constant *FuncOrBitcast) {
if (Function *F = dyn_cast<Function>(FuncOrBitcast))
return F;
std::string Err;
raw_string_ostream Stream(Err);
Stream << "SanitizerCoverage interface function redefined: "
<< *FuncOrBitcast;
report_fatal_error(Err);
}
bool SanitizerCoverageModule::runOnModule(Module &M) { bool SanitizerCoverageModule::runOnModule(Module &M) {
if (!CoverageLevel) return false; if (!CoverageLevel) return false;
C = &(M.getContext()); C = &(M.getContext());
@ -167,16 +157,18 @@ bool SanitizerCoverageModule::runOnModule(Module &M) {
ReturnInst::Create(*C, BasicBlock::Create(*C, "", CtorFunc)); ReturnInst::Create(*C, BasicBlock::Create(*C, "", CtorFunc));
appendToGlobalCtors(M, CtorFunc, kSanCtorAndDtorPriority); appendToGlobalCtors(M, CtorFunc, kSanCtorAndDtorPriority);
SanCovFunction = checkInterfaceFunction( SanCovFunction = checkSanitizerInterfaceFunction(
M.getOrInsertFunction(kSanCovName, VoidTy, Int32PtrTy, nullptr)); M.getOrInsertFunction(kSanCovName, VoidTy, Int32PtrTy, nullptr));
SanCovWithCheckFunction = checkInterfaceFunction( SanCovWithCheckFunction = checkSanitizerInterfaceFunction(
M.getOrInsertFunction(kSanCovWithCheckName, VoidTy, Int32PtrTy, nullptr)); M.getOrInsertFunction(kSanCovWithCheckName, VoidTy, Int32PtrTy, nullptr));
SanCovIndirCallFunction = checkInterfaceFunction(M.getOrInsertFunction( SanCovIndirCallFunction =
kSanCovIndirCallName, VoidTy, IntptrTy, IntptrTy, nullptr)); checkSanitizerInterfaceFunction(M.getOrInsertFunction(
SanCovTraceCmpFunction = checkInterfaceFunction(M.getOrInsertFunction( kSanCovIndirCallName, VoidTy, IntptrTy, IntptrTy, nullptr));
kSanCovTraceCmp, VoidTy, Int64Ty, Int64Ty, Int64Ty, nullptr)); SanCovTraceCmpFunction =
checkSanitizerInterfaceFunction(M.getOrInsertFunction(
kSanCovTraceCmp, VoidTy, Int64Ty, Int64Ty, Int64Ty, nullptr));
SanCovModuleInit = checkInterfaceFunction(M.getOrInsertFunction( SanCovModuleInit = checkSanitizerInterfaceFunction(M.getOrInsertFunction(
kSanCovModuleInitName, Type::getVoidTy(*C), Int32PtrTy, IntptrTy, kSanCovModuleInitName, Type::getVoidTy(*C), Int32PtrTy, IntptrTy,
Int8PtrTy, Int8PtrTy, nullptr)); Int8PtrTy, Int8PtrTy, nullptr));
SanCovModuleInit->setLinkage(Function::ExternalLinkage); SanCovModuleInit->setLinkage(Function::ExternalLinkage);
@ -186,9 +178,9 @@ bool SanitizerCoverageModule::runOnModule(Module &M) {
/*hasSideEffects=*/true); /*hasSideEffects=*/true);
if (ClExperimentalTracing) { if (ClExperimentalTracing) {
SanCovTraceEnter = checkInterfaceFunction( SanCovTraceEnter = checkSanitizerInterfaceFunction(
M.getOrInsertFunction(kSanCovTraceEnter, VoidTy, Int32PtrTy, nullptr)); M.getOrInsertFunction(kSanCovTraceEnter, VoidTy, Int32PtrTy, nullptr));
SanCovTraceBB = checkInterfaceFunction( SanCovTraceBB = checkSanitizerInterfaceFunction(
M.getOrInsertFunction(kSanCovTraceBB, VoidTy, Int32PtrTy, nullptr)); M.getOrInsertFunction(kSanCovTraceBB, VoidTy, Int32PtrTy, nullptr));
} }

View File

@ -129,54 +129,48 @@ FunctionPass *llvm::createThreadSanitizerPass() {
return new ThreadSanitizer(); return new ThreadSanitizer();
} }
static Function *checkInterfaceFunction(Constant *FuncOrBitcast) {
if (Function *F = dyn_cast<Function>(FuncOrBitcast))
return F;
FuncOrBitcast->dump();
report_fatal_error("ThreadSanitizer interface function redefined");
}
void ThreadSanitizer::initializeCallbacks(Module &M) { void ThreadSanitizer::initializeCallbacks(Module &M) {
IRBuilder<> IRB(M.getContext()); IRBuilder<> IRB(M.getContext());
// Initialize the callbacks. // Initialize the callbacks.
TsanFuncEntry = checkInterfaceFunction(M.getOrInsertFunction( TsanFuncEntry = checkSanitizerInterfaceFunction(M.getOrInsertFunction(
"__tsan_func_entry", IRB.getVoidTy(), IRB.getInt8PtrTy(), nullptr)); "__tsan_func_entry", IRB.getVoidTy(), IRB.getInt8PtrTy(), nullptr));
TsanFuncExit = checkInterfaceFunction(M.getOrInsertFunction( TsanFuncExit = checkSanitizerInterfaceFunction(
"__tsan_func_exit", IRB.getVoidTy(), nullptr)); M.getOrInsertFunction("__tsan_func_exit", IRB.getVoidTy(), nullptr));
OrdTy = IRB.getInt32Ty(); OrdTy = IRB.getInt32Ty();
for (size_t i = 0; i < kNumberOfAccessSizes; ++i) { for (size_t i = 0; i < kNumberOfAccessSizes; ++i) {
const size_t ByteSize = 1 << i; const size_t ByteSize = 1 << i;
const size_t BitSize = ByteSize * 8; const size_t BitSize = ByteSize * 8;
SmallString<32> ReadName("__tsan_read" + itostr(ByteSize)); SmallString<32> ReadName("__tsan_read" + itostr(ByteSize));
TsanRead[i] = checkInterfaceFunction(M.getOrInsertFunction( TsanRead[i] = checkSanitizerInterfaceFunction(M.getOrInsertFunction(
ReadName, IRB.getVoidTy(), IRB.getInt8PtrTy(), nullptr)); ReadName, IRB.getVoidTy(), IRB.getInt8PtrTy(), nullptr));
SmallString<32> WriteName("__tsan_write" + itostr(ByteSize)); SmallString<32> WriteName("__tsan_write" + itostr(ByteSize));
TsanWrite[i] = checkInterfaceFunction(M.getOrInsertFunction( TsanWrite[i] = checkSanitizerInterfaceFunction(M.getOrInsertFunction(
WriteName, IRB.getVoidTy(), IRB.getInt8PtrTy(), nullptr)); WriteName, IRB.getVoidTy(), IRB.getInt8PtrTy(), nullptr));
SmallString<64> UnalignedReadName("__tsan_unaligned_read" + SmallString<64> UnalignedReadName("__tsan_unaligned_read" +
itostr(ByteSize)); itostr(ByteSize));
TsanUnalignedRead[i] = checkInterfaceFunction(M.getOrInsertFunction( TsanUnalignedRead[i] =
UnalignedReadName, IRB.getVoidTy(), IRB.getInt8PtrTy(), nullptr)); checkSanitizerInterfaceFunction(M.getOrInsertFunction(
UnalignedReadName, IRB.getVoidTy(), IRB.getInt8PtrTy(), nullptr));
SmallString<64> UnalignedWriteName("__tsan_unaligned_write" + SmallString<64> UnalignedWriteName("__tsan_unaligned_write" +
itostr(ByteSize)); itostr(ByteSize));
TsanUnalignedWrite[i] = checkInterfaceFunction(M.getOrInsertFunction( TsanUnalignedWrite[i] =
UnalignedWriteName, IRB.getVoidTy(), IRB.getInt8PtrTy(), nullptr)); checkSanitizerInterfaceFunction(M.getOrInsertFunction(
UnalignedWriteName, IRB.getVoidTy(), IRB.getInt8PtrTy(), nullptr));
Type *Ty = Type::getIntNTy(M.getContext(), BitSize); Type *Ty = Type::getIntNTy(M.getContext(), BitSize);
Type *PtrTy = Ty->getPointerTo(); Type *PtrTy = Ty->getPointerTo();
SmallString<32> AtomicLoadName("__tsan_atomic" + itostr(BitSize) + SmallString<32> AtomicLoadName("__tsan_atomic" + itostr(BitSize) +
"_load"); "_load");
TsanAtomicLoad[i] = checkInterfaceFunction(M.getOrInsertFunction( TsanAtomicLoad[i] = checkSanitizerInterfaceFunction(
AtomicLoadName, Ty, PtrTy, OrdTy, nullptr)); M.getOrInsertFunction(AtomicLoadName, Ty, PtrTy, OrdTy, nullptr));
SmallString<32> AtomicStoreName("__tsan_atomic" + itostr(BitSize) + SmallString<32> AtomicStoreName("__tsan_atomic" + itostr(BitSize) +
"_store"); "_store");
TsanAtomicStore[i] = checkInterfaceFunction(M.getOrInsertFunction( TsanAtomicStore[i] = checkSanitizerInterfaceFunction(M.getOrInsertFunction(
AtomicStoreName, IRB.getVoidTy(), PtrTy, Ty, OrdTy, AtomicStoreName, IRB.getVoidTy(), PtrTy, Ty, OrdTy, nullptr));
nullptr));
for (int op = AtomicRMWInst::FIRST_BINOP; for (int op = AtomicRMWInst::FIRST_BINOP;
op <= AtomicRMWInst::LAST_BINOP; ++op) { op <= AtomicRMWInst::LAST_BINOP; ++op) {
@ -199,34 +193,34 @@ void ThreadSanitizer::initializeCallbacks(Module &M) {
else else
continue; continue;
SmallString<32> RMWName("__tsan_atomic" + itostr(BitSize) + NamePart); SmallString<32> RMWName("__tsan_atomic" + itostr(BitSize) + NamePart);
TsanAtomicRMW[op][i] = checkInterfaceFunction(M.getOrInsertFunction( TsanAtomicRMW[op][i] = checkSanitizerInterfaceFunction(
RMWName, Ty, PtrTy, Ty, OrdTy, nullptr)); M.getOrInsertFunction(RMWName, Ty, PtrTy, Ty, OrdTy, nullptr));
} }
SmallString<32> AtomicCASName("__tsan_atomic" + itostr(BitSize) + SmallString<32> AtomicCASName("__tsan_atomic" + itostr(BitSize) +
"_compare_exchange_val"); "_compare_exchange_val");
TsanAtomicCAS[i] = checkInterfaceFunction(M.getOrInsertFunction( TsanAtomicCAS[i] = checkSanitizerInterfaceFunction(M.getOrInsertFunction(
AtomicCASName, Ty, PtrTy, Ty, Ty, OrdTy, OrdTy, nullptr)); AtomicCASName, Ty, PtrTy, Ty, Ty, OrdTy, OrdTy, nullptr));
} }
TsanVptrUpdate = checkInterfaceFunction(M.getOrInsertFunction( TsanVptrUpdate = checkSanitizerInterfaceFunction(
"__tsan_vptr_update", IRB.getVoidTy(), IRB.getInt8PtrTy(), M.getOrInsertFunction("__tsan_vptr_update", IRB.getVoidTy(),
IRB.getInt8PtrTy(), nullptr)); IRB.getInt8PtrTy(), IRB.getInt8PtrTy(), nullptr));
TsanVptrLoad = checkInterfaceFunction(M.getOrInsertFunction( TsanVptrLoad = checkSanitizerInterfaceFunction(M.getOrInsertFunction(
"__tsan_vptr_read", IRB.getVoidTy(), IRB.getInt8PtrTy(), nullptr)); "__tsan_vptr_read", IRB.getVoidTy(), IRB.getInt8PtrTy(), nullptr));
TsanAtomicThreadFence = checkInterfaceFunction(M.getOrInsertFunction( TsanAtomicThreadFence = checkSanitizerInterfaceFunction(M.getOrInsertFunction(
"__tsan_atomic_thread_fence", IRB.getVoidTy(), OrdTy, nullptr)); "__tsan_atomic_thread_fence", IRB.getVoidTy(), OrdTy, nullptr));
TsanAtomicSignalFence = checkInterfaceFunction(M.getOrInsertFunction( TsanAtomicSignalFence = checkSanitizerInterfaceFunction(M.getOrInsertFunction(
"__tsan_atomic_signal_fence", IRB.getVoidTy(), OrdTy, nullptr)); "__tsan_atomic_signal_fence", IRB.getVoidTy(), OrdTy, nullptr));
MemmoveFn = checkInterfaceFunction(M.getOrInsertFunction( MemmoveFn = checkSanitizerInterfaceFunction(
"memmove", IRB.getInt8PtrTy(), IRB.getInt8PtrTy(), M.getOrInsertFunction("memmove", IRB.getInt8PtrTy(), IRB.getInt8PtrTy(),
IRB.getInt8PtrTy(), IntptrTy, nullptr)); IRB.getInt8PtrTy(), IntptrTy, nullptr));
MemcpyFn = checkInterfaceFunction(M.getOrInsertFunction( MemcpyFn = checkSanitizerInterfaceFunction(
"memcpy", IRB.getInt8PtrTy(), IRB.getInt8PtrTy(), IRB.getInt8PtrTy(), M.getOrInsertFunction("memcpy", IRB.getInt8PtrTy(), IRB.getInt8PtrTy(),
IntptrTy, nullptr)); IRB.getInt8PtrTy(), IntptrTy, nullptr));
MemsetFn = checkInterfaceFunction(M.getOrInsertFunction( MemsetFn = checkSanitizerInterfaceFunction(
"memset", IRB.getInt8PtrTy(), IRB.getInt8PtrTy(), IRB.getInt32Ty(), M.getOrInsertFunction("memset", IRB.getInt8PtrTy(), IRB.getInt8PtrTy(),
IntptrTy, nullptr)); IRB.getInt32Ty(), IntptrTy, nullptr));
} }
bool ThreadSanitizer::doInitialization(Module &M) { bool ThreadSanitizer::doInitialization(Module &M) {

View File

@ -17,6 +17,7 @@
#include "llvm/IR/Function.h" #include "llvm/IR/Function.h"
#include "llvm/IR/IRBuilder.h" #include "llvm/IR/IRBuilder.h"
#include "llvm/IR/Module.h" #include "llvm/IR/Module.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm; using namespace llvm;
@ -93,3 +94,13 @@ llvm::collectUsedGlobalVariables(Module &M, SmallPtrSetImpl<GlobalValue *> &Set,
} }
return GV; return GV;
} }
Function *llvm::checkSanitizerInterfaceFunction(Constant *FuncOrBitcast) {
if (isa<Function>(FuncOrBitcast))
return cast<Function>(FuncOrBitcast);
FuncOrBitcast->dump();
std::string Err;
raw_string_ostream Stream(Err);
Stream << "Sanitizer interface function redefined: " << *FuncOrBitcast;
report_fatal_error(Err);
}