mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-05-17 15:38:40 +00:00
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:
parent
af1023588e
commit
aa5880df12
@ -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
|
||||||
|
@ -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));
|
||||||
}
|
}
|
||||||
|
@ -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));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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) {
|
||||||
|
@ -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);
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user