diff options
Diffstat (limited to 'llvm/lib/Transforms/Instrumentation')
9 files changed, 400 insertions, 376 deletions
diff --git a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp index bae04a3d413..1a007b4258f 100644 --- a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp @@ -715,19 +715,19 @@ private: Type *IntptrTy; ShadowMapping Mapping; DominatorTree *DT; - FunctionCallee AsanHandleNoReturnFunc; - FunctionCallee AsanPtrCmpFunction, AsanPtrSubFunction; + Function *AsanHandleNoReturnFunc; + Function *AsanPtrCmpFunction, *AsanPtrSubFunction; Constant *AsanShadowGlobal; // These arrays is indexed by AccessIsWrite, Experiment and log2(AccessSize). - FunctionCallee AsanErrorCallback[2][2][kNumberOfAccessSizes]; - FunctionCallee AsanMemoryAccessCallback[2][2][kNumberOfAccessSizes]; + Function *AsanErrorCallback[2][2][kNumberOfAccessSizes]; + Function *AsanMemoryAccessCallback[2][2][kNumberOfAccessSizes]; // These arrays is indexed by AccessIsWrite and Experiment. - FunctionCallee AsanErrorCallbackSized[2][2]; - FunctionCallee AsanMemoryAccessCallbackSized[2][2]; + Function *AsanErrorCallbackSized[2][2]; + Function *AsanMemoryAccessCallbackSized[2][2]; - FunctionCallee AsanMemmove, AsanMemcpy, AsanMemset; + Function *AsanMemmove, *AsanMemcpy, *AsanMemset; InlineAsm *EmptyAsm; Value *LocalDynamicShadow = nullptr; GlobalsMetadata GlobalsMD; @@ -809,14 +809,14 @@ private: LLVMContext *C; Triple TargetTriple; ShadowMapping Mapping; - FunctionCallee AsanPoisonGlobals; - FunctionCallee AsanUnpoisonGlobals; - FunctionCallee AsanRegisterGlobals; - FunctionCallee AsanUnregisterGlobals; - FunctionCallee AsanRegisterImageGlobals; - FunctionCallee AsanUnregisterImageGlobals; - FunctionCallee AsanRegisterElfGlobals; - FunctionCallee AsanUnregisterElfGlobals; + Function *AsanPoisonGlobals; + Function *AsanUnpoisonGlobals; + Function *AsanRegisterGlobals; + Function *AsanUnregisterGlobals; + Function *AsanRegisterImageGlobals; + Function *AsanUnregisterImageGlobals; + Function *AsanRegisterElfGlobals; + Function *AsanUnregisterElfGlobals; Function *AsanCtorFunction = nullptr; Function *AsanDtorFunction = nullptr; @@ -845,11 +845,11 @@ struct FunctionStackPoisoner : public InstVisitor<FunctionStackPoisoner> { SmallVector<Instruction *, 8> RetVec; unsigned StackAlignment; - FunctionCallee AsanStackMallocFunc[kMaxAsanStackMallocSizeClass + 1], - AsanStackFreeFunc[kMaxAsanStackMallocSizeClass + 1]; - FunctionCallee AsanSetShadowFunc[0x100] = {}; - FunctionCallee AsanPoisonStackMemoryFunc, AsanUnpoisonStackMemoryFunc; - FunctionCallee AsanAllocaPoisonFunc, AsanAllocasUnpoisonFunc; + Function *AsanStackMallocFunc[kMaxAsanStackMallocSizeClass + 1], + *AsanStackFreeFunc[kMaxAsanStackMallocSizeClass + 1]; + Function *AsanSetShadowFunc[0x100] = {}; + Function *AsanPoisonStackMemoryFunc, *AsanUnpoisonStackMemoryFunc; + Function *AsanAllocaPoisonFunc, *AsanAllocasUnpoisonFunc; // Stores a place and arguments of poisoning/unpoisoning call for alloca. struct AllocaPoisonCall { @@ -1333,7 +1333,7 @@ bool AddressSanitizer::GlobalIsLinkerInitialized(GlobalVariable *G) { void AddressSanitizer::instrumentPointerComparisonOrSubtraction( Instruction *I) { IRBuilder<> IRB(I); - FunctionCallee F = isa<ICmpInst>(I) ? AsanPtrCmpFunction : AsanPtrSubFunction; + Function *F = isa<ICmpInst>(I) ? AsanPtrCmpFunction : AsanPtrSubFunction; Value *Param[2] = {I->getOperand(0), I->getOperand(1)}; for (Value *&i : Param) { if (i->getType()->isPointerTy()) @@ -1795,30 +1795,43 @@ void AddressSanitizerModule::initializeCallbacks(Module &M) { IRBuilder<> IRB(*C); // Declare our poisoning and unpoisoning functions. - AsanPoisonGlobals = - M.getOrInsertFunction(kAsanPoisonGlobalsName, IRB.getVoidTy(), IntptrTy); - AsanUnpoisonGlobals = - M.getOrInsertFunction(kAsanUnpoisonGlobalsName, IRB.getVoidTy()); + AsanPoisonGlobals = checkSanitizerInterfaceFunction(M.getOrInsertFunction( + kAsanPoisonGlobalsName, IRB.getVoidTy(), IntptrTy)); + AsanPoisonGlobals->setLinkage(Function::ExternalLinkage); + AsanUnpoisonGlobals = checkSanitizerInterfaceFunction(M.getOrInsertFunction( + kAsanUnpoisonGlobalsName, IRB.getVoidTy())); + AsanUnpoisonGlobals->setLinkage(Function::ExternalLinkage); // Declare functions that register/unregister globals. - AsanRegisterGlobals = M.getOrInsertFunction( - kAsanRegisterGlobalsName, IRB.getVoidTy(), IntptrTy, IntptrTy); - AsanUnregisterGlobals = M.getOrInsertFunction( - kAsanUnregisterGlobalsName, IRB.getVoidTy(), IntptrTy, IntptrTy); + AsanRegisterGlobals = checkSanitizerInterfaceFunction(M.getOrInsertFunction( + kAsanRegisterGlobalsName, IRB.getVoidTy(), IntptrTy, IntptrTy)); + AsanRegisterGlobals->setLinkage(Function::ExternalLinkage); + AsanUnregisterGlobals = checkSanitizerInterfaceFunction( + M.getOrInsertFunction(kAsanUnregisterGlobalsName, IRB.getVoidTy(), + IntptrTy, IntptrTy)); + AsanUnregisterGlobals->setLinkage(Function::ExternalLinkage); // Declare the functions that find globals in a shared object and then invoke // the (un)register function on them. - AsanRegisterImageGlobals = M.getOrInsertFunction( - kAsanRegisterImageGlobalsName, IRB.getVoidTy(), IntptrTy); - AsanUnregisterImageGlobals = M.getOrInsertFunction( - kAsanUnregisterImageGlobalsName, IRB.getVoidTy(), IntptrTy); + AsanRegisterImageGlobals = + checkSanitizerInterfaceFunction(M.getOrInsertFunction( + kAsanRegisterImageGlobalsName, IRB.getVoidTy(), IntptrTy)); + AsanRegisterImageGlobals->setLinkage(Function::ExternalLinkage); - AsanRegisterElfGlobals = + AsanUnregisterImageGlobals = + checkSanitizerInterfaceFunction(M.getOrInsertFunction( + kAsanUnregisterImageGlobalsName, IRB.getVoidTy(), IntptrTy)); + AsanUnregisterImageGlobals->setLinkage(Function::ExternalLinkage); + + AsanRegisterElfGlobals = checkSanitizerInterfaceFunction( M.getOrInsertFunction(kAsanRegisterElfGlobalsName, IRB.getVoidTy(), - IntptrTy, IntptrTy, IntptrTy); - AsanUnregisterElfGlobals = + IntptrTy, IntptrTy, IntptrTy)); + AsanRegisterElfGlobals->setLinkage(Function::ExternalLinkage); + + AsanUnregisterElfGlobals = checkSanitizerInterfaceFunction( M.getOrInsertFunction(kAsanUnregisterElfGlobalsName, IRB.getVoidTy(), - IntptrTy, IntptrTy, IntptrTy); + IntptrTy, IntptrTy, IntptrTy)); + AsanUnregisterElfGlobals->setLinkage(Function::ExternalLinkage); } // Put the metadata and the instrumented global in the same group. This ensures @@ -2332,49 +2345,51 @@ void AddressSanitizer::initializeCallbacks(Module &M) { Args2.push_back(ExpType); Args1.push_back(ExpType); } - AsanErrorCallbackSized[AccessIsWrite][Exp] = M.getOrInsertFunction( - kAsanReportErrorTemplate + ExpStr + TypeStr + "_n" + EndingStr, - FunctionType::get(IRB.getVoidTy(), Args2, false)); + AsanErrorCallbackSized[AccessIsWrite][Exp] = + checkSanitizerInterfaceFunction(M.getOrInsertFunction( + kAsanReportErrorTemplate + ExpStr + TypeStr + "_n" + EndingStr, + FunctionType::get(IRB.getVoidTy(), Args2, false))); - AsanMemoryAccessCallbackSized[AccessIsWrite][Exp] = M.getOrInsertFunction( - ClMemoryAccessCallbackPrefix + ExpStr + TypeStr + "N" + EndingStr, - FunctionType::get(IRB.getVoidTy(), Args2, false)); + AsanMemoryAccessCallbackSized[AccessIsWrite][Exp] = + checkSanitizerInterfaceFunction(M.getOrInsertFunction( + ClMemoryAccessCallbackPrefix + ExpStr + TypeStr + "N" + EndingStr, + FunctionType::get(IRB.getVoidTy(), Args2, false))); for (size_t AccessSizeIndex = 0; AccessSizeIndex < kNumberOfAccessSizes; AccessSizeIndex++) { const std::string Suffix = TypeStr + itostr(1ULL << AccessSizeIndex); AsanErrorCallback[AccessIsWrite][Exp][AccessSizeIndex] = - M.getOrInsertFunction( + checkSanitizerInterfaceFunction(M.getOrInsertFunction( kAsanReportErrorTemplate + ExpStr + Suffix + EndingStr, - FunctionType::get(IRB.getVoidTy(), Args1, false)); + FunctionType::get(IRB.getVoidTy(), Args1, false))); AsanMemoryAccessCallback[AccessIsWrite][Exp][AccessSizeIndex] = - M.getOrInsertFunction( + checkSanitizerInterfaceFunction(M.getOrInsertFunction( ClMemoryAccessCallbackPrefix + ExpStr + Suffix + EndingStr, - FunctionType::get(IRB.getVoidTy(), Args1, false)); + FunctionType::get(IRB.getVoidTy(), Args1, false))); } } } const std::string MemIntrinCallbackPrefix = CompileKernel ? std::string("") : ClMemoryAccessCallbackPrefix; - AsanMemmove = M.getOrInsertFunction(MemIntrinCallbackPrefix + "memmove", - IRB.getInt8PtrTy(), IRB.getInt8PtrTy(), - IRB.getInt8PtrTy(), IntptrTy); - AsanMemcpy = M.getOrInsertFunction(MemIntrinCallbackPrefix + "memcpy", - IRB.getInt8PtrTy(), IRB.getInt8PtrTy(), - IRB.getInt8PtrTy(), IntptrTy); - AsanMemset = M.getOrInsertFunction(MemIntrinCallbackPrefix + "memset", - IRB.getInt8PtrTy(), IRB.getInt8PtrTy(), - IRB.getInt32Ty(), IntptrTy); - - AsanHandleNoReturnFunc = - M.getOrInsertFunction(kAsanHandleNoReturnName, IRB.getVoidTy()); - - AsanPtrCmpFunction = - M.getOrInsertFunction(kAsanPtrCmp, IRB.getVoidTy(), IntptrTy, IntptrTy); - AsanPtrSubFunction = - M.getOrInsertFunction(kAsanPtrSub, IRB.getVoidTy(), IntptrTy, IntptrTy); + AsanMemmove = checkSanitizerInterfaceFunction(M.getOrInsertFunction( + MemIntrinCallbackPrefix + "memmove", IRB.getInt8PtrTy(), + IRB.getInt8PtrTy(), IRB.getInt8PtrTy(), IntptrTy)); + AsanMemcpy = checkSanitizerInterfaceFunction(M.getOrInsertFunction( + MemIntrinCallbackPrefix + "memcpy", IRB.getInt8PtrTy(), + IRB.getInt8PtrTy(), IRB.getInt8PtrTy(), IntptrTy)); + AsanMemset = checkSanitizerInterfaceFunction(M.getOrInsertFunction( + MemIntrinCallbackPrefix + "memset", IRB.getInt8PtrTy(), + IRB.getInt8PtrTy(), IRB.getInt32Ty(), IntptrTy)); + + AsanHandleNoReturnFunc = checkSanitizerInterfaceFunction( + M.getOrInsertFunction(kAsanHandleNoReturnName, IRB.getVoidTy())); + + AsanPtrCmpFunction = checkSanitizerInterfaceFunction(M.getOrInsertFunction( + kAsanPtrCmp, IRB.getVoidTy(), IntptrTy, IntptrTy)); + AsanPtrSubFunction = checkSanitizerInterfaceFunction(M.getOrInsertFunction( + kAsanPtrSub, IRB.getVoidTy(), IntptrTy, IntptrTy)); // We insert an empty inline asm after __asan_report* to avoid callback merge. EmptyAsm = InlineAsm::get(FunctionType::get(IRB.getVoidTy(), false), StringRef(""), StringRef(""), @@ -2412,7 +2427,7 @@ bool AddressSanitizer::maybeInsertAsanInitAtFunctionEntry(Function &F) { // We cannot just ignore these methods, because they may call other // instrumented functions. if (F.getName().find(" load]") != std::string::npos) { - FunctionCallee AsanInitFunction = + Function *AsanInitFunction = declareSanitizerInitFunction(*F.getParent(), kAsanInitName, {}); IRBuilder<> IRB(&F.front(), F.front().begin()); IRB.CreateCall(AsanInitFunction, {}); @@ -2627,17 +2642,20 @@ void FunctionStackPoisoner::initializeCallbacks(Module &M) { IRBuilder<> IRB(*C); for (int i = 0; i <= kMaxAsanStackMallocSizeClass; i++) { std::string Suffix = itostr(i); - AsanStackMallocFunc[i] = M.getOrInsertFunction( - kAsanStackMallocNameTemplate + Suffix, IntptrTy, IntptrTy); - AsanStackFreeFunc[i] = + AsanStackMallocFunc[i] = checkSanitizerInterfaceFunction( + M.getOrInsertFunction(kAsanStackMallocNameTemplate + Suffix, IntptrTy, + IntptrTy)); + AsanStackFreeFunc[i] = checkSanitizerInterfaceFunction( M.getOrInsertFunction(kAsanStackFreeNameTemplate + Suffix, - IRB.getVoidTy(), IntptrTy, IntptrTy); + IRB.getVoidTy(), IntptrTy, IntptrTy)); } if (ASan.UseAfterScope) { - AsanPoisonStackMemoryFunc = M.getOrInsertFunction( - kAsanPoisonStackMemoryName, IRB.getVoidTy(), IntptrTy, IntptrTy); - AsanUnpoisonStackMemoryFunc = M.getOrInsertFunction( - kAsanUnpoisonStackMemoryName, IRB.getVoidTy(), IntptrTy, IntptrTy); + AsanPoisonStackMemoryFunc = checkSanitizerInterfaceFunction( + M.getOrInsertFunction(kAsanPoisonStackMemoryName, IRB.getVoidTy(), + IntptrTy, IntptrTy)); + AsanUnpoisonStackMemoryFunc = checkSanitizerInterfaceFunction( + M.getOrInsertFunction(kAsanUnpoisonStackMemoryName, IRB.getVoidTy(), + IntptrTy, IntptrTy)); } for (size_t Val : {0x00, 0xf1, 0xf2, 0xf3, 0xf5, 0xf8}) { @@ -2645,13 +2663,15 @@ void FunctionStackPoisoner::initializeCallbacks(Module &M) { Name << kAsanSetShadowPrefix; Name << std::setw(2) << std::setfill('0') << std::hex << Val; AsanSetShadowFunc[Val] = - M.getOrInsertFunction(Name.str(), IRB.getVoidTy(), IntptrTy, IntptrTy); + checkSanitizerInterfaceFunction(M.getOrInsertFunction( + Name.str(), IRB.getVoidTy(), IntptrTy, IntptrTy)); } - AsanAllocaPoisonFunc = M.getOrInsertFunction( - kAsanAllocaPoison, IRB.getVoidTy(), IntptrTy, IntptrTy); - AsanAllocasUnpoisonFunc = M.getOrInsertFunction( - kAsanAllocasUnpoison, IRB.getVoidTy(), IntptrTy, IntptrTy); + AsanAllocaPoisonFunc = checkSanitizerInterfaceFunction(M.getOrInsertFunction( + kAsanAllocaPoison, IRB.getVoidTy(), IntptrTy, IntptrTy)); + AsanAllocasUnpoisonFunc = + checkSanitizerInterfaceFunction(M.getOrInsertFunction( + kAsanAllocasUnpoison, IRB.getVoidTy(), IntptrTy, IntptrTy)); } void FunctionStackPoisoner::copyToShadowInline(ArrayRef<uint8_t> ShadowMask, diff --git a/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp index 790609388c3..58220b81bb6 100644 --- a/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp @@ -341,13 +341,13 @@ class DataFlowSanitizer : public ModulePass { FunctionType *DFSanSetLabelFnTy; FunctionType *DFSanNonzeroLabelFnTy; FunctionType *DFSanVarargWrapperFnTy; - FunctionCallee DFSanUnionFn; - FunctionCallee DFSanCheckedUnionFn; - FunctionCallee DFSanUnionLoadFn; - FunctionCallee DFSanUnimplementedFn; - FunctionCallee DFSanSetLabelFn; - FunctionCallee DFSanNonzeroLabelFn; - FunctionCallee DFSanVarargWrapperFn; + Constant *DFSanUnionFn; + Constant *DFSanCheckedUnionFn; + Constant *DFSanUnionLoadFn; + Constant *DFSanUnimplementedFn; + Constant *DFSanSetLabelFn; + Constant *DFSanNonzeroLabelFn; + Constant *DFSanVarargWrapperFn; MDNode *ColdCallWeights; DFSanABIList ABIList; DenseMap<Value *, Function *> UnwrappedFnMap; @@ -677,8 +677,8 @@ DataFlowSanitizer::buildWrapperFunction(Function *F, StringRef NewFName, Constant *DataFlowSanitizer::getOrBuildTrampolineFunction(FunctionType *FT, StringRef FName) { FunctionType *FTT = getTrampolineFunctionType(FT); - FunctionCallee C = Mod->getOrInsertFunction(FName, FTT); - Function *F = dyn_cast<Function>(C.getCallee()); + Constant *C = Mod->getOrInsertFunction(FName, FTT); + Function *F = dyn_cast<Function>(C); if (F && F->isDeclaration()) { F->setLinkage(GlobalValue::LinkOnceODRLinkage); BasicBlock *BB = BasicBlock::Create(*Ctx, "entry", F); @@ -703,7 +703,7 @@ Constant *DataFlowSanitizer::getOrBuildTrampolineFunction(FunctionType *FT, &*std::prev(F->arg_end()), RI); } - return cast<Constant>(C.getCallee()); + return C; } bool DataFlowSanitizer::runOnModule(Module &M) { @@ -725,51 +725,35 @@ bool DataFlowSanitizer::runOnModule(Module &M) { ExternalShadowMask = Mod->getOrInsertGlobal(kDFSanExternShadowPtrMask, IntptrTy); - { - AttributeList AL; - AL = AL.addAttribute(M.getContext(), AttributeList::FunctionIndex, - Attribute::NoUnwind); - AL = AL.addAttribute(M.getContext(), AttributeList::FunctionIndex, - Attribute::ReadNone); - AL = AL.addAttribute(M.getContext(), AttributeList::ReturnIndex, - Attribute::ZExt); - AL = AL.addParamAttribute(M.getContext(), 0, Attribute::ZExt); - AL = AL.addParamAttribute(M.getContext(), 1, Attribute::ZExt); - DFSanUnionFn = - Mod->getOrInsertFunction("__dfsan_union", DFSanUnionFnTy, AL); + DFSanUnionFn = Mod->getOrInsertFunction("__dfsan_union", DFSanUnionFnTy); + if (Function *F = dyn_cast<Function>(DFSanUnionFn)) { + F->addAttribute(AttributeList::FunctionIndex, Attribute::NoUnwind); + F->addAttribute(AttributeList::FunctionIndex, Attribute::ReadNone); + F->addAttribute(AttributeList::ReturnIndex, Attribute::ZExt); + F->addParamAttr(0, Attribute::ZExt); + F->addParamAttr(1, Attribute::ZExt); } - - { - AttributeList AL; - AL = AL.addAttribute(M.getContext(), AttributeList::FunctionIndex, - Attribute::NoUnwind); - AL = AL.addAttribute(M.getContext(), AttributeList::FunctionIndex, - Attribute::ReadNone); - AL = AL.addAttribute(M.getContext(), AttributeList::ReturnIndex, - Attribute::ZExt); - AL = AL.addParamAttribute(M.getContext(), 0, Attribute::ZExt); - AL = AL.addParamAttribute(M.getContext(), 1, Attribute::ZExt); - DFSanCheckedUnionFn = - Mod->getOrInsertFunction("dfsan_union", DFSanUnionFnTy, AL); + DFSanCheckedUnionFn = Mod->getOrInsertFunction("dfsan_union", DFSanUnionFnTy); + if (Function *F = dyn_cast<Function>(DFSanCheckedUnionFn)) { + F->addAttribute(AttributeList::FunctionIndex, Attribute::NoUnwind); + F->addAttribute(AttributeList::FunctionIndex, Attribute::ReadNone); + F->addAttribute(AttributeList::ReturnIndex, Attribute::ZExt); + F->addParamAttr(0, Attribute::ZExt); + F->addParamAttr(1, Attribute::ZExt); } - { - AttributeList AL; - AL = AL.addAttribute(M.getContext(), AttributeList::FunctionIndex, - Attribute::NoUnwind); - AL = AL.addAttribute(M.getContext(), AttributeList::FunctionIndex, - Attribute::ReadOnly); - AL = AL.addAttribute(M.getContext(), AttributeList::ReturnIndex, - Attribute::ZExt); - DFSanUnionLoadFn = - Mod->getOrInsertFunction("__dfsan_union_load", DFSanUnionLoadFnTy, AL); + DFSanUnionLoadFn = + Mod->getOrInsertFunction("__dfsan_union_load", DFSanUnionLoadFnTy); + if (Function *F = dyn_cast<Function>(DFSanUnionLoadFn)) { + F->addAttribute(AttributeList::FunctionIndex, Attribute::NoUnwind); + F->addAttribute(AttributeList::FunctionIndex, Attribute::ReadOnly); + F->addAttribute(AttributeList::ReturnIndex, Attribute::ZExt); } DFSanUnimplementedFn = Mod->getOrInsertFunction("__dfsan_unimplemented", DFSanUnimplementedFnTy); - { - AttributeList AL; - AL = AL.addParamAttribute(M.getContext(), 0, Attribute::ZExt); - DFSanSetLabelFn = - Mod->getOrInsertFunction("__dfsan_set_label", DFSanSetLabelFnTy, AL); + DFSanSetLabelFn = + Mod->getOrInsertFunction("__dfsan_set_label", DFSanSetLabelFnTy); + if (Function *F = dyn_cast<Function>(DFSanSetLabelFn)) { + F->addParamAttr(0, Attribute::ZExt); } DFSanNonzeroLabelFn = Mod->getOrInsertFunction("__dfsan_nonzero_label", DFSanNonzeroLabelFnTy); @@ -780,13 +764,13 @@ bool DataFlowSanitizer::runOnModule(Module &M) { SmallPtrSet<Function *, 2> FnsWithNativeABI; for (Function &i : M) { if (!i.isIntrinsic() && - &i != DFSanUnionFn.getCallee()->stripPointerCasts() && - &i != DFSanCheckedUnionFn.getCallee()->stripPointerCasts() && - &i != DFSanUnionLoadFn.getCallee()->stripPointerCasts() && - &i != DFSanUnimplementedFn.getCallee()->stripPointerCasts() && - &i != DFSanSetLabelFn.getCallee()->stripPointerCasts() && - &i != DFSanNonzeroLabelFn.getCallee()->stripPointerCasts() && - &i != DFSanVarargWrapperFn.getCallee()->stripPointerCasts()) + &i != DFSanUnionFn && + &i != DFSanCheckedUnionFn && + &i != DFSanUnionLoadFn && + &i != DFSanUnimplementedFn && + &i != DFSanSetLabelFn && + &i != DFSanNonzeroLabelFn && + &i != DFSanVarargWrapperFn) FnsToInstrument.push_back(&i); } @@ -1528,7 +1512,7 @@ void DFSanVisitor::visitCallSite(CallSite CS) { // Calls to this function are synthesized in wrappers, and we shouldn't // instrument them. - if (F == DFSF.DFS.DFSanVarargWrapperFn.getCallee()->stripPointerCasts()) + if (F == DFSF.DFS.DFSanVarargWrapperFn) return; IRBuilder<> IRB(CS.getInstruction()); @@ -1561,9 +1545,9 @@ void DFSanVisitor::visitCallSite(CallSite CS) { TransformedFunction CustomFn = DFSF.DFS.getCustomFunctionType(FT); std::string CustomFName = "__dfsw_"; CustomFName += F->getName(); - FunctionCallee CustomF = DFSF.DFS.Mod->getOrInsertFunction( + Constant *CustomF = DFSF.DFS.Mod->getOrInsertFunction( CustomFName, CustomFn.TransformedType); - if (Function *CustomFn = dyn_cast<Function>(CustomF.getCallee())) { + if (Function *CustomFn = dyn_cast<Function>(CustomF)) { CustomFn->copyAttributesFrom(F); // Custom functions returning non-void will write to the return label. diff --git a/llvm/lib/Transforms/Instrumentation/EfficiencySanitizer.cpp b/llvm/lib/Transforms/Instrumentation/EfficiencySanitizer.cpp index 14b05662c3e..bb146dab584 100644 --- a/llvm/lib/Transforms/Instrumentation/EfficiencySanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/EfficiencySanitizer.cpp @@ -202,13 +202,13 @@ private: // Our slowpath involves callouts to the runtime library. // Access sizes are powers of two: 1, 2, 4, 8, 16. static const size_t NumberOfAccessSizes = 5; - FunctionCallee EsanAlignedLoad[NumberOfAccessSizes]; - FunctionCallee EsanAlignedStore[NumberOfAccessSizes]; - FunctionCallee EsanUnalignedLoad[NumberOfAccessSizes]; - FunctionCallee EsanUnalignedStore[NumberOfAccessSizes]; + Function *EsanAlignedLoad[NumberOfAccessSizes]; + Function *EsanAlignedStore[NumberOfAccessSizes]; + Function *EsanUnalignedLoad[NumberOfAccessSizes]; + Function *EsanUnalignedStore[NumberOfAccessSizes]; // For irregular sizes of any alignment: - FunctionCallee EsanUnalignedLoadN, EsanUnalignedStoreN; - FunctionCallee MemmoveFn, MemcpyFn, MemsetFn; + Function *EsanUnalignedLoadN, *EsanUnalignedStoreN; + Function *MemmoveFn, *MemcpyFn, *MemsetFn; Function *EsanCtorFunction; Function *EsanDtorFunction; // Remember the counter variable for each struct type to avoid @@ -249,31 +249,37 @@ void EfficiencySanitizer::initializeCallbacks(Module &M) { // We'll inline the most common (i.e., aligned and frequent sizes) // load + store instrumentation: these callouts are for the slowpath. SmallString<32> AlignedLoadName("__esan_aligned_load" + ByteSizeStr); - EsanAlignedLoad[Idx] = M.getOrInsertFunction( - AlignedLoadName, IRB.getVoidTy(), IRB.getInt8PtrTy()); + EsanAlignedLoad[Idx] = + checkSanitizerInterfaceFunction(M.getOrInsertFunction( + AlignedLoadName, IRB.getVoidTy(), IRB.getInt8PtrTy())); SmallString<32> AlignedStoreName("__esan_aligned_store" + ByteSizeStr); - EsanAlignedStore[Idx] = M.getOrInsertFunction( - AlignedStoreName, IRB.getVoidTy(), IRB.getInt8PtrTy()); + EsanAlignedStore[Idx] = + checkSanitizerInterfaceFunction(M.getOrInsertFunction( + AlignedStoreName, IRB.getVoidTy(), IRB.getInt8PtrTy())); SmallString<32> UnalignedLoadName("__esan_unaligned_load" + ByteSizeStr); - EsanUnalignedLoad[Idx] = M.getOrInsertFunction( - UnalignedLoadName, IRB.getVoidTy(), IRB.getInt8PtrTy()); + EsanUnalignedLoad[Idx] = + checkSanitizerInterfaceFunction(M.getOrInsertFunction( + UnalignedLoadName, IRB.getVoidTy(), IRB.getInt8PtrTy())); SmallString<32> UnalignedStoreName("__esan_unaligned_store" + ByteSizeStr); - EsanUnalignedStore[Idx] = M.getOrInsertFunction( - UnalignedStoreName, IRB.getVoidTy(), IRB.getInt8PtrTy()); + EsanUnalignedStore[Idx] = + checkSanitizerInterfaceFunction(M.getOrInsertFunction( + UnalignedStoreName, IRB.getVoidTy(), IRB.getInt8PtrTy())); } - EsanUnalignedLoadN = M.getOrInsertFunction( - "__esan_unaligned_loadN", IRB.getVoidTy(), IRB.getInt8PtrTy(), IntptrTy); - EsanUnalignedStoreN = M.getOrInsertFunction( - "__esan_unaligned_storeN", IRB.getVoidTy(), IRB.getInt8PtrTy(), IntptrTy); - MemmoveFn = + EsanUnalignedLoadN = checkSanitizerInterfaceFunction( + M.getOrInsertFunction("__esan_unaligned_loadN", IRB.getVoidTy(), + IRB.getInt8PtrTy(), IntptrTy)); + EsanUnalignedStoreN = checkSanitizerInterfaceFunction( + M.getOrInsertFunction("__esan_unaligned_storeN", IRB.getVoidTy(), + IRB.getInt8PtrTy(), IntptrTy)); + MemmoveFn = checkSanitizerInterfaceFunction( M.getOrInsertFunction("memmove", IRB.getInt8PtrTy(), IRB.getInt8PtrTy(), - IRB.getInt8PtrTy(), IntptrTy); - MemcpyFn = + IRB.getInt8PtrTy(), IntptrTy)); + MemcpyFn = checkSanitizerInterfaceFunction( M.getOrInsertFunction("memcpy", IRB.getInt8PtrTy(), IRB.getInt8PtrTy(), - IRB.getInt8PtrTy(), IntptrTy); - MemsetFn = + IRB.getInt8PtrTy(), IntptrTy)); + MemsetFn = checkSanitizerInterfaceFunction( M.getOrInsertFunction("memset", IRB.getInt8PtrTy(), IRB.getInt8PtrTy(), - IRB.getInt32Ty(), IntptrTy); + IRB.getInt32Ty(), IntptrTy)); } bool EfficiencySanitizer::shouldIgnoreStructType(StructType *StructTy) { @@ -504,8 +510,10 @@ void EfficiencySanitizer::createDestructor(Module &M, Constant *ToolInfoArg) { EsanModuleDtorName, &M); ReturnInst::Create(*Ctx, BasicBlock::Create(*Ctx, "", EsanDtorFunction)); IRBuilder<> IRB_Dtor(EsanDtorFunction->getEntryBlock().getTerminator()); - FunctionCallee EsanExit = - M.getOrInsertFunction(EsanExitName, IRB_Dtor.getVoidTy(), Int8PtrTy); + Function *EsanExit = checkSanitizerInterfaceFunction( + M.getOrInsertFunction(EsanExitName, IRB_Dtor.getVoidTy(), + Int8PtrTy)); + EsanExit->setLinkage(Function::ExternalLinkage); IRB_Dtor.CreateCall(EsanExit, {ToolInfoArg}); appendToGlobalDtors(M, EsanDtorFunction, EsanCtorAndDtorPriority); } @@ -661,7 +669,7 @@ bool EfficiencySanitizer::instrumentLoadOrStore(Instruction *I, Type *OrigTy = cast<PointerType>(Addr->getType())->getElementType(); const uint32_t TypeSizeBytes = DL.getTypeStoreSizeInBits(OrigTy) / 8; - FunctionCallee OnAccessFunc = nullptr; + Value *OnAccessFunc = nullptr; // Convert 0 to the default alignment. if (Alignment == 0) diff --git a/llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp b/llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp index eeaf214f0ab..a1a65e2d33b 100644 --- a/llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp +++ b/llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp @@ -102,11 +102,11 @@ private: std::vector<Regex> &Regexes); // Get pointers to the functions in the runtime library. - FunctionCallee getStartFileFunc(); - FunctionCallee getEmitFunctionFunc(); - FunctionCallee getEmitArcsFunc(); - FunctionCallee getSummaryInfoFunc(); - FunctionCallee getEndFileFunc(); + Constant *getStartFileFunc(); + Constant *getEmitFunctionFunc(); + Constant *getEmitArcsFunc(); + Constant *getSummaryInfoFunc(); + Constant *getEndFileFunc(); // Add the function to write out all our counters to the global destructor // list. @@ -647,7 +647,7 @@ void GCOVProfiler::AddFlushBeforeForkAndExec() { for (auto I : ForkAndExecs) { IRBuilder<> Builder(I); FunctionType *FTy = FunctionType::get(Builder.getVoidTy(), {}, false); - FunctionCallee GCOVFlush = M->getOrInsertFunction("__gcov_flush", FTy); + Constant *GCOVFlush = M->getOrInsertFunction("__gcov_flush", FTy); Builder.CreateCall(GCOVFlush); I->getParent()->splitBasicBlock(I); } @@ -863,7 +863,7 @@ bool GCOVProfiler::emitProfileArcs() { // Initialize the environment and register the local writeout and flush // functions. - FunctionCallee GCOVInit = M->getOrInsertFunction("llvm_gcov_init", FTy); + Constant *GCOVInit = M->getOrInsertFunction("llvm_gcov_init", FTy); Builder.CreateCall(GCOVInit, {WriteoutF, FlushF}); Builder.CreateRetVoid(); @@ -873,21 +873,22 @@ bool GCOVProfiler::emitProfileArcs() { return Result; } -FunctionCallee GCOVProfiler::getStartFileFunc() { +Constant *GCOVProfiler::getStartFileFunc() { Type *Args[] = { Type::getInt8PtrTy(*Ctx), // const char *orig_filename Type::getInt8PtrTy(*Ctx), // const char version[4] Type::getInt32Ty(*Ctx), // uint32_t checksum }; FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), Args, false); - AttributeList AL; - if (auto AK = TLI->getExtAttrForI32Param(false)) - AL = AL.addParamAttribute(*Ctx, 2, AK); - FunctionCallee Res = M->getOrInsertFunction("llvm_gcda_start_file", FTy, AL); + auto *Res = M->getOrInsertFunction("llvm_gcda_start_file", FTy); + if (Function *FunRes = dyn_cast<Function>(Res)) + if (auto AK = TLI->getExtAttrForI32Param(false)) + FunRes->addParamAttr(2, AK); return Res; + } -FunctionCallee GCOVProfiler::getEmitFunctionFunc() { +Constant *GCOVProfiler::getEmitFunctionFunc() { Type *Args[] = { Type::getInt32Ty(*Ctx), // uint32_t ident Type::getInt8PtrTy(*Ctx), // const char *function_name @@ -896,34 +897,36 @@ FunctionCallee GCOVProfiler::getEmitFunctionFunc() { Type::getInt32Ty(*Ctx), // uint32_t cfg_checksum }; FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), Args, false); - AttributeList AL; - if (auto AK = TLI->getExtAttrForI32Param(false)) { - AL = AL.addParamAttribute(*Ctx, 0, AK); - AL = AL.addParamAttribute(*Ctx, 2, AK); - AL = AL.addParamAttribute(*Ctx, 3, AK); - AL = AL.addParamAttribute(*Ctx, 4, AK); - } - return M->getOrInsertFunction("llvm_gcda_emit_function", FTy); + auto *Res = M->getOrInsertFunction("llvm_gcda_emit_function", FTy); + if (Function *FunRes = dyn_cast<Function>(Res)) + if (auto AK = TLI->getExtAttrForI32Param(false)) { + FunRes->addParamAttr(0, AK); + FunRes->addParamAttr(2, AK); + FunRes->addParamAttr(3, AK); + FunRes->addParamAttr(4, AK); + } + return Res; } -FunctionCallee GCOVProfiler::getEmitArcsFunc() { +Constant *GCOVProfiler::getEmitArcsFunc() { Type *Args[] = { Type::getInt32Ty(*Ctx), // uint32_t num_counters Type::getInt64PtrTy(*Ctx), // uint64_t *counters }; FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), Args, false); - AttributeList AL; - if (auto AK = TLI->getExtAttrForI32Param(false)) - AL = AL.addParamAttribute(*Ctx, 0, AK); - return M->getOrInsertFunction("llvm_gcda_emit_arcs", FTy, AL); + auto *Res = M->getOrInsertFunction("llvm_gcda_emit_arcs", FTy); + if (Function *FunRes = dyn_cast<Function>(Res)) + if (auto AK = TLI->getExtAttrForI32Param(false)) + FunRes->addParamAttr(0, AK); + return Res; } -FunctionCallee GCOVProfiler::getSummaryInfoFunc() { +Constant *GCOVProfiler::getSummaryInfoFunc() { FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), false); return M->getOrInsertFunction("llvm_gcda_summary_info", FTy); } -FunctionCallee GCOVProfiler::getEndFileFunc() { +Constant *GCOVProfiler::getEndFileFunc() { FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), false); return M->getOrInsertFunction("llvm_gcda_end_file", FTy); } @@ -943,11 +946,11 @@ Function *GCOVProfiler::insertCounterWriteout( BasicBlock *BB = BasicBlock::Create(*Ctx, "entry", WriteoutF); IRBuilder<> Builder(BB); - FunctionCallee StartFile = getStartFileFunc(); - FunctionCallee EmitFunction = getEmitFunctionFunc(); - FunctionCallee EmitArcs = getEmitArcsFunc(); - FunctionCallee SummaryInfo = getSummaryInfoFunc(); - FunctionCallee EndFile = getEndFileFunc(); + Constant *StartFile = getStartFileFunc(); + Constant *EmitFunction = getEmitFunctionFunc(); + Constant *EmitArcs = getEmitArcsFunc(); + Constant *SummaryInfo = getSummaryInfoFunc(); + Constant *EndFile = getEndFileFunc(); NamedMDNode *CUNodes = M->getNamedMetadata("llvm.dbg.cu"); if (!CUNodes) { diff --git a/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp index 405dc5320cd..a6ffff418db 100644 --- a/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp @@ -221,7 +221,7 @@ private: LLVMContext *C; std::string CurModuleUniqueId; Triple TargetTriple; - FunctionCallee HWAsanMemmove, HWAsanMemcpy, HWAsanMemset; + Function *HWAsanMemmove, *HWAsanMemcpy, *HWAsanMemset; // Frame description is a way to pass names/sizes of local variables // to the run-time w/o adding extra executable code in every function. @@ -270,12 +270,12 @@ private: Function *HwasanCtorFunction; - FunctionCallee HwasanMemoryAccessCallback[2][kNumberOfAccessSizes]; - FunctionCallee HwasanMemoryAccessCallbackSized[2]; + Function *HwasanMemoryAccessCallback[2][kNumberOfAccessSizes]; + Function *HwasanMemoryAccessCallbackSized[2]; - FunctionCallee HwasanTagMemoryFunc; - FunctionCallee HwasanGenerateTagFunc; - FunctionCallee HwasanThreadEnterFunc; + Function *HwasanTagMemoryFunc; + Function *HwasanGenerateTagFunc; + Function *HwasanThreadEnterFunc; Constant *ShadowGlobal; @@ -369,42 +369,43 @@ void HWAddressSanitizer::initializeCallbacks(Module &M) { const std::string TypeStr = AccessIsWrite ? "store" : "load"; const std::string EndingStr = Recover ? "_noabort" : ""; - HwasanMemoryAccessCallbackSized[AccessIsWrite] = M.getOrInsertFunction( - ClMemoryAccessCallbackPrefix + TypeStr + "N" + EndingStr, - FunctionType::get(IRB.getVoidTy(), {IntptrTy, IntptrTy}, false)); + HwasanMemoryAccessCallbackSized[AccessIsWrite] = + checkSanitizerInterfaceFunction(M.getOrInsertFunction( + ClMemoryAccessCallbackPrefix + TypeStr + "N" + EndingStr, + FunctionType::get(IRB.getVoidTy(), {IntptrTy, IntptrTy}, false))); for (size_t AccessSizeIndex = 0; AccessSizeIndex < kNumberOfAccessSizes; AccessSizeIndex++) { HwasanMemoryAccessCallback[AccessIsWrite][AccessSizeIndex] = - M.getOrInsertFunction( + checkSanitizerInterfaceFunction(M.getOrInsertFunction( ClMemoryAccessCallbackPrefix + TypeStr + itostr(1ULL << AccessSizeIndex) + EndingStr, - FunctionType::get(IRB.getVoidTy(), {IntptrTy}, false)); + FunctionType::get(IRB.getVoidTy(), {IntptrTy}, false))); } } - HwasanTagMemoryFunc = M.getOrInsertFunction( - "__hwasan_tag_memory", IRB.getVoidTy(), Int8PtrTy, Int8Ty, IntptrTy); - HwasanGenerateTagFunc = - M.getOrInsertFunction("__hwasan_generate_tag", Int8Ty); + HwasanTagMemoryFunc = checkSanitizerInterfaceFunction(M.getOrInsertFunction( + "__hwasan_tag_memory", IRB.getVoidTy(), Int8PtrTy, Int8Ty, IntptrTy)); + HwasanGenerateTagFunc = checkSanitizerInterfaceFunction( + M.getOrInsertFunction("__hwasan_generate_tag", Int8Ty)); ShadowGlobal = M.getOrInsertGlobal("__hwasan_shadow", ArrayType::get(IRB.getInt8Ty(), 0)); const std::string MemIntrinCallbackPrefix = CompileKernel ? std::string("") : ClMemoryAccessCallbackPrefix; - HWAsanMemmove = M.getOrInsertFunction(MemIntrinCallbackPrefix + "memmove", - IRB.getInt8PtrTy(), IRB.getInt8PtrTy(), - IRB.getInt8PtrTy(), IntptrTy); - HWAsanMemcpy = M.getOrInsertFunction(MemIntrinCallbackPrefix + "memcpy", - IRB.getInt8PtrTy(), IRB.getInt8PtrTy(), - IRB.getInt8PtrTy(), IntptrTy); - HWAsanMemset = M.getOrInsertFunction(MemIntrinCallbackPrefix + "memset", - IRB.getInt8PtrTy(), IRB.getInt8PtrTy(), - IRB.getInt32Ty(), IntptrTy); - - HwasanThreadEnterFunc = - M.getOrInsertFunction("__hwasan_thread_enter", IRB.getVoidTy()); + HWAsanMemmove = checkSanitizerInterfaceFunction(M.getOrInsertFunction( + MemIntrinCallbackPrefix + "memmove", IRB.getInt8PtrTy(), + IRB.getInt8PtrTy(), IRB.getInt8PtrTy(), IntptrTy)); + HWAsanMemcpy = checkSanitizerInterfaceFunction(M.getOrInsertFunction( + MemIntrinCallbackPrefix + "memcpy", IRB.getInt8PtrTy(), + IRB.getInt8PtrTy(), IRB.getInt8PtrTy(), IntptrTy)); + HWAsanMemset = checkSanitizerInterfaceFunction(M.getOrInsertFunction( + MemIntrinCallbackPrefix + "memset", IRB.getInt8PtrTy(), + IRB.getInt8PtrTy(), IRB.getInt32Ty(), IntptrTy)); + + HwasanThreadEnterFunc = checkSanitizerInterfaceFunction( + M.getOrInsertFunction("__hwasan_thread_enter", IRB.getVoidTy())); } Value *HWAddressSanitizer::getDynamicShadowIfunc(IRBuilder<> &IRB) { diff --git a/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp b/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp index dc032ac0a5b..0877d734b02 100644 --- a/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp +++ b/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp @@ -508,16 +508,13 @@ bool InstrProfiling::run(Module &M, const TargetLibraryInfo &TLI) { return true; } -static FunctionCallee -getOrInsertValueProfilingCall(Module &M, const TargetLibraryInfo &TLI, - bool IsRange = false) { +static Constant *getOrInsertValueProfilingCall(Module &M, + const TargetLibraryInfo &TLI, + bool IsRange = false) { LLVMContext &Ctx = M.getContext(); auto *ReturnTy = Type::getVoidTy(M.getContext()); - AttributeList AL; - if (auto AK = TLI.getExtAttrForI32Param(false)) - AL = AL.addParamAttribute(M.getContext(), 2, AK); - + Constant *Res; if (!IsRange) { Type *ParamTypes[] = { #define VALUE_PROF_FUNC_PARAM(ParamType, ParamName, ParamLLVMType) ParamLLVMType @@ -525,8 +522,8 @@ getOrInsertValueProfilingCall(Module &M, const TargetLibraryInfo &TLI, }; auto *ValueProfilingCallTy = FunctionType::get(ReturnTy, makeArrayRef(ParamTypes), false); - return M.getOrInsertFunction(getInstrProfValueProfFuncName(), - ValueProfilingCallTy, AL); + Res = M.getOrInsertFunction(getInstrProfValueProfFuncName(), + ValueProfilingCallTy); } else { Type *RangeParamTypes[] = { #define VALUE_RANGE_PROF 1 @@ -536,9 +533,15 @@ getOrInsertValueProfilingCall(Module &M, const TargetLibraryInfo &TLI, }; auto *ValueRangeProfilingCallTy = FunctionType::get(ReturnTy, makeArrayRef(RangeParamTypes), false); - return M.getOrInsertFunction(getInstrProfValueRangeProfFuncName(), - ValueRangeProfilingCallTy, AL); + Res = M.getOrInsertFunction(getInstrProfValueRangeProfFuncName(), + ValueRangeProfilingCallTy); + } + + if (Function *FunRes = dyn_cast<Function>(Res)) { + if (auto AK = TLI.getExtAttrForI32Param(false)) + FunRes->addParamAttr(2, AK); } + return Res; } void InstrProfiling::computeNumValueSiteCounts(InstrProfValueProfileInst *Ind) { diff --git a/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp b/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp index e18dcbf31c5..12fd8a099e3 100644 --- a/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp @@ -536,41 +536,41 @@ private: bool CallbacksInitialized = false; /// The run-time callback to print a warning. - FunctionCallee WarningFn; + Value *WarningFn; // These arrays are indexed by log2(AccessSize). - FunctionCallee MaybeWarningFn[kNumberOfAccessSizes]; - FunctionCallee MaybeStoreOriginFn[kNumberOfAccessSizes]; + Value *MaybeWarningFn[kNumberOfAccessSizes]; + Value *MaybeStoreOriginFn[kNumberOfAccessSizes]; /// Run-time helper that generates a new origin value for a stack /// allocation. - FunctionCallee MsanSetAllocaOrigin4Fn; + Value *MsanSetAllocaOrigin4Fn; /// Run-time helper that poisons stack on function entry. - FunctionCallee MsanPoisonStackFn; + Value *MsanPoisonStackFn; /// Run-time helper that records a store (or any event) of an /// uninitialized value and returns an updated origin id encoding this info. - FunctionCallee MsanChainOriginFn; + Value *MsanChainOriginFn; /// MSan runtime replacements for memmove, memcpy and memset. - FunctionCallee MemmoveFn, MemcpyFn, MemsetFn; + Value *MemmoveFn, *MemcpyFn, *MemsetFn; /// KMSAN callback for task-local function argument shadow. - FunctionCallee MsanGetContextStateFn; + Value *MsanGetContextStateFn; /// Functions for poisoning/unpoisoning local variables - FunctionCallee MsanPoisonAllocaFn, MsanUnpoisonAllocaFn; + Value *MsanPoisonAllocaFn, *MsanUnpoisonAllocaFn; /// Each of the MsanMetadataPtrXxx functions returns a pair of shadow/origin /// pointers. - FunctionCallee MsanMetadataPtrForLoadN, MsanMetadataPtrForStoreN; - FunctionCallee MsanMetadataPtrForLoad_1_8[4]; - FunctionCallee MsanMetadataPtrForStore_1_8[4]; - FunctionCallee MsanInstrumentAsmStoreFn; + Value *MsanMetadataPtrForLoadN, *MsanMetadataPtrForStoreN; + Value *MsanMetadataPtrForLoad_1_8[4]; + Value *MsanMetadataPtrForStore_1_8[4]; + Value *MsanInstrumentAsmStoreFn; /// Helper to choose between different MsanMetadataPtrXxx(). - FunctionCallee getKmsanShadowOriginAccessFn(bool isStore, int size); + Value *getKmsanShadowOriginAccessFn(bool isStore, int size); /// Memory map parameters used in application-to-shadow calculation. const MemoryMapParams *MapParams; @@ -823,9 +823,8 @@ void MemorySanitizer::initializeCallbacks(Module &M) { CallbacksInitialized = true; } -FunctionCallee MemorySanitizer::getKmsanShadowOriginAccessFn(bool isStore, - int size) { - FunctionCallee *Fns = +Value *MemorySanitizer::getKmsanShadowOriginAccessFn(bool isStore, int size) { + Value **Fns = isStore ? MsanMetadataPtrForStore_1_8 : MsanMetadataPtrForLoad_1_8; switch (size) { case 1: @@ -925,7 +924,7 @@ void MemorySanitizer::initializeModule(Module &M) { /*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) { + [&](Function *Ctor, Function *) { if (!ClWithComdat) { appendToGlobalCtors(M, Ctor, 0); return; @@ -1124,7 +1123,7 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> { DL.getTypeSizeInBits(ConvertedShadow->getType()); unsigned SizeIndex = TypeSizeToSizeIndex(TypeSizeInBits); if (AsCall && SizeIndex < kNumberOfAccessSizes && !MS.CompileKernel) { - FunctionCallee Fn = MS.MaybeStoreOriginFn[SizeIndex]; + Value *Fn = MS.MaybeStoreOriginFn[SizeIndex]; Value *ConvertedShadow2 = IRB.CreateZExt( ConvertedShadow, IRB.getIntNTy(8 * (1 << SizeIndex))); IRB.CreateCall(Fn, {ConvertedShadow2, @@ -1206,7 +1205,7 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> { unsigned TypeSizeInBits = DL.getTypeSizeInBits(ConvertedShadow->getType()); unsigned SizeIndex = TypeSizeToSizeIndex(TypeSizeInBits); if (AsCall && SizeIndex < kNumberOfAccessSizes && !MS.CompileKernel) { - FunctionCallee Fn = MS.MaybeWarningFn[SizeIndex]; + Value *Fn = MS.MaybeWarningFn[SizeIndex]; Value *ConvertedShadow2 = IRB.CreateZExt(ConvertedShadow, IRB.getIntNTy(8 * (1 << SizeIndex))); IRB.CreateCall(Fn, {ConvertedShadow2, MS.TrackOrigins && Origin @@ -1413,7 +1412,7 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> { const DataLayout &DL = F.getParent()->getDataLayout(); int Size = DL.getTypeStoreSize(ShadowTy); - FunctionCallee Getter = MS.getKmsanShadowOriginAccessFn(isStore, Size); + Value *Getter = MS.getKmsanShadowOriginAccessFn(isStore, Size); Value *AddrCast = IRB.CreatePointerCast(Addr, PointerType::get(IRB.getInt8Ty(), 0)); if (Getter) { diff --git a/llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp b/llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp index e0c1365ce5e..6d98c66ee68 100644 --- a/llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp +++ b/llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp @@ -222,13 +222,13 @@ private: std::string getSectionName(const std::string &Section) const; std::string getSectionStart(const std::string &Section) const; std::string getSectionEnd(const std::string &Section) const; - FunctionCallee SanCovTracePCIndir; - FunctionCallee SanCovTracePC, SanCovTracePCGuard; - FunctionCallee SanCovTraceCmpFunction[4]; - FunctionCallee SanCovTraceConstCmpFunction[4]; - FunctionCallee SanCovTraceDivFunction[2]; - FunctionCallee SanCovTraceGepFunction; - FunctionCallee SanCovTraceSwitchFunction; + Function *SanCovTracePCIndir; + Function *SanCovTracePC, *SanCovTracePCGuard; + Function *SanCovTraceCmpFunction[4]; + Function *SanCovTraceConstCmpFunction[4]; + Function *SanCovTraceDivFunction[2]; + Function *SanCovTraceGepFunction; + Function *SanCovTraceSwitchFunction; GlobalVariable *SanCovLowestStack; InlineAsm *EmptyAsm; Type *IntptrTy, *IntptrPtrTy, *Int64Ty, *Int64PtrTy, *Int32Ty, *Int32PtrTy, @@ -328,52 +328,46 @@ bool SanitizerCoverageModule::runOnModule(Module &M) { Int16Ty = IRB.getInt16Ty(); Int8Ty = IRB.getInt8Ty(); - SanCovTracePCIndir = - M.getOrInsertFunction(SanCovTracePCIndirName, VoidTy, IntptrTy); - // Make sure smaller parameters are zero-extended to i64 as required by the - // x86_64 ABI. - AttributeList SanCovTraceCmpZeroExtAL; - if (TargetTriple.getArch() == Triple::x86_64) { - SanCovTraceCmpZeroExtAL = - SanCovTraceCmpZeroExtAL.addParamAttribute(*C, 0, Attribute::ZExt); - SanCovTraceCmpZeroExtAL = - SanCovTraceCmpZeroExtAL.addParamAttribute(*C, 1, Attribute::ZExt); - } - + SanCovTracePCIndir = checkSanitizerInterfaceFunction( + M.getOrInsertFunction(SanCovTracePCIndirName, VoidTy, IntptrTy)); SanCovTraceCmpFunction[0] = - M.getOrInsertFunction(SanCovTraceCmp1, SanCovTraceCmpZeroExtAL, VoidTy, - IRB.getInt8Ty(), IRB.getInt8Ty()); - SanCovTraceCmpFunction[1] = - M.getOrInsertFunction(SanCovTraceCmp2, SanCovTraceCmpZeroExtAL, VoidTy, - IRB.getInt16Ty(), IRB.getInt16Ty()); - SanCovTraceCmpFunction[2] = - M.getOrInsertFunction(SanCovTraceCmp4, SanCovTraceCmpZeroExtAL, VoidTy, - IRB.getInt32Ty(), IRB.getInt32Ty()); + checkSanitizerInterfaceFunction(M.getOrInsertFunction( + SanCovTraceCmp1, VoidTy, IRB.getInt8Ty(), IRB.getInt8Ty())); + SanCovTraceCmpFunction[1] = checkSanitizerInterfaceFunction( + M.getOrInsertFunction(SanCovTraceCmp2, VoidTy, IRB.getInt16Ty(), + IRB.getInt16Ty())); + SanCovTraceCmpFunction[2] = checkSanitizerInterfaceFunction( + M.getOrInsertFunction(SanCovTraceCmp4, VoidTy, IRB.getInt32Ty(), + IRB.getInt32Ty())); SanCovTraceCmpFunction[3] = - M.getOrInsertFunction(SanCovTraceCmp8, VoidTy, Int64Ty, Int64Ty); - - SanCovTraceConstCmpFunction[0] = M.getOrInsertFunction( - SanCovTraceConstCmp1, SanCovTraceCmpZeroExtAL, VoidTy, Int8Ty, Int8Ty); - SanCovTraceConstCmpFunction[1] = M.getOrInsertFunction( - SanCovTraceConstCmp2, SanCovTraceCmpZeroExtAL, VoidTy, Int16Ty, Int16Ty); - SanCovTraceConstCmpFunction[2] = M.getOrInsertFunction( - SanCovTraceConstCmp4, SanCovTraceCmpZeroExtAL, VoidTy, Int32Ty, Int32Ty); + checkSanitizerInterfaceFunction(M.getOrInsertFunction( + SanCovTraceCmp8, VoidTy, Int64Ty, Int64Ty)); + + SanCovTraceConstCmpFunction[0] = + checkSanitizerInterfaceFunction(M.getOrInsertFunction( + SanCovTraceConstCmp1, VoidTy, Int8Ty, Int8Ty)); + SanCovTraceConstCmpFunction[1] = + checkSanitizerInterfaceFunction(M.getOrInsertFunction( + SanCovTraceConstCmp2, VoidTy, Int16Ty, Int16Ty)); + SanCovTraceConstCmpFunction[2] = + checkSanitizerInterfaceFunction(M.getOrInsertFunction( + SanCovTraceConstCmp4, VoidTy, Int32Ty, Int32Ty)); SanCovTraceConstCmpFunction[3] = - M.getOrInsertFunction(SanCovTraceConstCmp8, VoidTy, Int64Ty, Int64Ty); - - { - AttributeList AL; - if (TargetTriple.getArch() == Triple::x86_64) - AL = AL.addParamAttribute(*C, 0, Attribute::ZExt); - SanCovTraceDivFunction[0] = - M.getOrInsertFunction(SanCovTraceDiv4, AL, VoidTy, IRB.getInt32Ty()); - } + checkSanitizerInterfaceFunction(M.getOrInsertFunction( + SanCovTraceConstCmp8, VoidTy, Int64Ty, Int64Ty)); + + SanCovTraceDivFunction[0] = + checkSanitizerInterfaceFunction(M.getOrInsertFunction( + SanCovTraceDiv4, VoidTy, IRB.getInt32Ty())); SanCovTraceDivFunction[1] = - M.getOrInsertFunction(SanCovTraceDiv8, VoidTy, Int64Ty); + checkSanitizerInterfaceFunction(M.getOrInsertFunction( + SanCovTraceDiv8, VoidTy, Int64Ty)); SanCovTraceGepFunction = - M.getOrInsertFunction(SanCovTraceGep, VoidTy, IntptrTy); + checkSanitizerInterfaceFunction(M.getOrInsertFunction( + SanCovTraceGep, VoidTy, IntptrTy)); SanCovTraceSwitchFunction = - M.getOrInsertFunction(SanCovTraceSwitchName, VoidTy, Int64Ty, Int64PtrTy); + checkSanitizerInterfaceFunction(M.getOrInsertFunction( + SanCovTraceSwitchName, VoidTy, Int64Ty, Int64PtrTy)); Constant *SanCovLowestStackConstant = M.getOrInsertGlobal(SanCovLowestStackName, IntptrTy); @@ -383,14 +377,28 @@ bool SanitizerCoverageModule::runOnModule(Module &M) { if (Options.StackDepth && !SanCovLowestStack->isDeclaration()) SanCovLowestStack->setInitializer(Constant::getAllOnesValue(IntptrTy)); + // Make sure smaller parameters are zero-extended to i64 as required by the + // x86_64 ABI. + if (TargetTriple.getArch() == Triple::x86_64) { + for (int i = 0; i < 3; i++) { + SanCovTraceCmpFunction[i]->addParamAttr(0, Attribute::ZExt); + SanCovTraceCmpFunction[i]->addParamAttr(1, Attribute::ZExt); + SanCovTraceConstCmpFunction[i]->addParamAttr(0, Attribute::ZExt); + SanCovTraceConstCmpFunction[i]->addParamAttr(1, Attribute::ZExt); + } + SanCovTraceDivFunction[0]->addParamAttr(0, Attribute::ZExt); + } + + // We insert an empty inline asm after cov callbacks to avoid callback merge. EmptyAsm = InlineAsm::get(FunctionType::get(IRB.getVoidTy(), false), StringRef(""), StringRef(""), /*hasSideEffects=*/true); - SanCovTracePC = M.getOrInsertFunction(SanCovTracePCName, VoidTy); - SanCovTracePCGuard = - M.getOrInsertFunction(SanCovTracePCGuardName, VoidTy, Int32PtrTy); + SanCovTracePC = checkSanitizerInterfaceFunction( + M.getOrInsertFunction(SanCovTracePCName, VoidTy)); + SanCovTracePCGuard = checkSanitizerInterfaceFunction(M.getOrInsertFunction( + SanCovTracePCGuardName, VoidTy, Int32PtrTy)); for (auto &F : M) runOnFunction(F); @@ -405,7 +413,7 @@ bool SanitizerCoverageModule::runOnModule(Module &M) { SanCovCountersSectionName); if (Ctor && Options.PCTable) { auto SecStartEnd = CreateSecStartEnd(M, SanCovPCsSectionName, IntptrPtrTy); - FunctionCallee InitFunction = declareSanitizerInitFunction( + Function *InitFunction = declareSanitizerInitFunction( M, SanCovPCsInitName, {IntptrPtrTy, IntptrPtrTy}); IRBuilder<> IRBCtor(Ctor->getEntryBlock().getTerminator()); IRBCtor.CreateCall(InitFunction, {SecStartEnd.first, SecStartEnd.second}); diff --git a/llvm/lib/Transforms/Instrumentation/ThreadSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/ThreadSanitizer.cpp index 5be13fa745c..4be485c50d2 100644 --- a/llvm/lib/Transforms/Instrumentation/ThreadSanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/ThreadSanitizer.cpp @@ -110,26 +110,25 @@ private: Type *IntptrTy; IntegerType *OrdTy; // Callbacks to run-time library are computed in doInitialization. - FunctionCallee TsanFuncEntry; - FunctionCallee TsanFuncExit; - FunctionCallee TsanIgnoreBegin; - FunctionCallee TsanIgnoreEnd; + Function *TsanFuncEntry; + Function *TsanFuncExit; + Function *TsanIgnoreBegin; + Function *TsanIgnoreEnd; // Accesses sizes are powers of two: 1, 2, 4, 8, 16. static const size_t kNumberOfAccessSizes = 5; - FunctionCallee TsanRead[kNumberOfAccessSizes]; - FunctionCallee TsanWrite[kNumberOfAccessSizes]; - FunctionCallee TsanUnalignedRead[kNumberOfAccessSizes]; - FunctionCallee TsanUnalignedWrite[kNumberOfAccessSizes]; - FunctionCallee TsanAtomicLoad[kNumberOfAccessSizes]; - FunctionCallee TsanAtomicStore[kNumberOfAccessSizes]; - FunctionCallee TsanAtomicRMW[AtomicRMWInst::LAST_BINOP + 1] - [kNumberOfAccessSizes]; - FunctionCallee TsanAtomicCAS[kNumberOfAccessSizes]; - FunctionCallee TsanAtomicThreadFence; - FunctionCallee TsanAtomicSignalFence; - FunctionCallee TsanVptrUpdate; - FunctionCallee TsanVptrLoad; - FunctionCallee MemmoveFn, MemcpyFn, MemsetFn; + Function *TsanRead[kNumberOfAccessSizes]; + Function *TsanWrite[kNumberOfAccessSizes]; + Function *TsanUnalignedRead[kNumberOfAccessSizes]; + Function *TsanUnalignedWrite[kNumberOfAccessSizes]; + Function *TsanAtomicLoad[kNumberOfAccessSizes]; + Function *TsanAtomicStore[kNumberOfAccessSizes]; + Function *TsanAtomicRMW[AtomicRMWInst::LAST_BINOP + 1][kNumberOfAccessSizes]; + Function *TsanAtomicCAS[kNumberOfAccessSizes]; + Function *TsanAtomicThreadFence; + Function *TsanAtomicSignalFence; + Function *TsanVptrUpdate; + Function *TsanVptrLoad; + Function *MemmoveFn, *MemcpyFn, *MemsetFn; Function *TsanCtorFunction; }; @@ -189,14 +188,14 @@ void ThreadSanitizer::initializeCallbacks(Module &M) { Attr = Attr.addAttribute(M.getContext(), AttributeList::FunctionIndex, Attribute::NoUnwind); // Initialize the callbacks. - TsanFuncEntry = M.getOrInsertFunction("__tsan_func_entry", Attr, - IRB.getVoidTy(), IRB.getInt8PtrTy()); - TsanFuncExit = - M.getOrInsertFunction("__tsan_func_exit", Attr, IRB.getVoidTy()); - TsanIgnoreBegin = M.getOrInsertFunction("__tsan_ignore_thread_begin", Attr, - IRB.getVoidTy()); - TsanIgnoreEnd = - M.getOrInsertFunction("__tsan_ignore_thread_end", Attr, IRB.getVoidTy()); + TsanFuncEntry = checkSanitizerInterfaceFunction(M.getOrInsertFunction( + "__tsan_func_entry", Attr, IRB.getVoidTy(), IRB.getInt8PtrTy())); + TsanFuncExit = checkSanitizerInterfaceFunction( + M.getOrInsertFunction("__tsan_func_exit", Attr, IRB.getVoidTy())); + TsanIgnoreBegin = checkSanitizerInterfaceFunction(M.getOrInsertFunction( + "__tsan_ignore_thread_begin", Attr, IRB.getVoidTy())); + TsanIgnoreEnd = checkSanitizerInterfaceFunction(M.getOrInsertFunction( + "__tsan_ignore_thread_end", Attr, IRB.getVoidTy())); OrdTy = IRB.getInt32Ty(); for (size_t i = 0; i < kNumberOfAccessSizes; ++i) { const unsigned ByteSize = 1U << i; @@ -204,30 +203,32 @@ void ThreadSanitizer::initializeCallbacks(Module &M) { std::string ByteSizeStr = utostr(ByteSize); std::string BitSizeStr = utostr(BitSize); SmallString<32> ReadName("__tsan_read" + ByteSizeStr); - TsanRead[i] = M.getOrInsertFunction(ReadName, Attr, IRB.getVoidTy(), - IRB.getInt8PtrTy()); + TsanRead[i] = checkSanitizerInterfaceFunction(M.getOrInsertFunction( + ReadName, Attr, IRB.getVoidTy(), IRB.getInt8PtrTy())); SmallString<32> WriteName("__tsan_write" + ByteSizeStr); - TsanWrite[i] = M.getOrInsertFunction(WriteName, Attr, IRB.getVoidTy(), - IRB.getInt8PtrTy()); + TsanWrite[i] = checkSanitizerInterfaceFunction(M.getOrInsertFunction( + WriteName, Attr, IRB.getVoidTy(), IRB.getInt8PtrTy())); SmallString<64> UnalignedReadName("__tsan_unaligned_read" + ByteSizeStr); - TsanUnalignedRead[i] = M.getOrInsertFunction( - UnalignedReadName, Attr, IRB.getVoidTy(), IRB.getInt8PtrTy()); + TsanUnalignedRead[i] = + checkSanitizerInterfaceFunction(M.getOrInsertFunction( + UnalignedReadName, Attr, IRB.getVoidTy(), IRB.getInt8PtrTy())); SmallString<64> UnalignedWriteName("__tsan_unaligned_write" + ByteSizeStr); - TsanUnalignedWrite[i] = M.getOrInsertFunction( - UnalignedWriteName, Attr, IRB.getVoidTy(), IRB.getInt8PtrTy()); + TsanUnalignedWrite[i] = + checkSanitizerInterfaceFunction(M.getOrInsertFunction( + UnalignedWriteName, Attr, IRB.getVoidTy(), IRB.getInt8PtrTy())); Type *Ty = Type::getIntNTy(M.getContext(), BitSize); Type *PtrTy = Ty->getPointerTo(); SmallString<32> AtomicLoadName("__tsan_atomic" + BitSizeStr + "_load"); - TsanAtomicLoad[i] = - M.getOrInsertFunction(AtomicLoadName, Attr, Ty, PtrTy, OrdTy); + TsanAtomicLoad[i] = checkSanitizerInterfaceFunction( + M.getOrInsertFunction(AtomicLoadName, Attr, Ty, PtrTy, OrdTy)); SmallString<32> AtomicStoreName("__tsan_atomic" + BitSizeStr + "_store"); - TsanAtomicStore[i] = M.getOrInsertFunction( - AtomicStoreName, Attr, IRB.getVoidTy(), PtrTy, Ty, OrdTy); + TsanAtomicStore[i] = checkSanitizerInterfaceFunction(M.getOrInsertFunction( + AtomicStoreName, Attr, IRB.getVoidTy(), PtrTy, Ty, OrdTy)); for (int op = AtomicRMWInst::FIRST_BINOP; op <= AtomicRMWInst::LAST_BINOP; ++op) { @@ -250,34 +251,34 @@ void ThreadSanitizer::initializeCallbacks(Module &M) { else continue; SmallString<32> RMWName("__tsan_atomic" + itostr(BitSize) + NamePart); - TsanAtomicRMW[op][i] = - M.getOrInsertFunction(RMWName, Attr, Ty, PtrTy, Ty, OrdTy); + TsanAtomicRMW[op][i] = checkSanitizerInterfaceFunction( + M.getOrInsertFunction(RMWName, Attr, Ty, PtrTy, Ty, OrdTy)); } SmallString<32> AtomicCASName("__tsan_atomic" + BitSizeStr + "_compare_exchange_val"); - TsanAtomicCAS[i] = M.getOrInsertFunction(AtomicCASName, Attr, Ty, PtrTy, Ty, - Ty, OrdTy, OrdTy); + TsanAtomicCAS[i] = checkSanitizerInterfaceFunction(M.getOrInsertFunction( + AtomicCASName, Attr, Ty, PtrTy, Ty, Ty, OrdTy, OrdTy)); } - TsanVptrUpdate = + TsanVptrUpdate = checkSanitizerInterfaceFunction( M.getOrInsertFunction("__tsan_vptr_update", Attr, IRB.getVoidTy(), - IRB.getInt8PtrTy(), IRB.getInt8PtrTy()); - TsanVptrLoad = M.getOrInsertFunction("__tsan_vptr_read", Attr, - IRB.getVoidTy(), IRB.getInt8PtrTy()); - TsanAtomicThreadFence = M.getOrInsertFunction("__tsan_atomic_thread_fence", - Attr, IRB.getVoidTy(), OrdTy); - TsanAtomicSignalFence = M.getOrInsertFunction("__tsan_atomic_signal_fence", - Attr, IRB.getVoidTy(), OrdTy); - - MemmoveFn = - M.getOrInsertFunction("memmove", Attr, IRB.getInt8PtrTy(), - IRB.getInt8PtrTy(), IRB.getInt8PtrTy(), IntptrTy); - MemcpyFn = - M.getOrInsertFunction("memcpy", Attr, IRB.getInt8PtrTy(), - IRB.getInt8PtrTy(), IRB.getInt8PtrTy(), IntptrTy); - MemsetFn = - M.getOrInsertFunction("memset", Attr, IRB.getInt8PtrTy(), - IRB.getInt8PtrTy(), IRB.getInt32Ty(), IntptrTy); + IRB.getInt8PtrTy(), IRB.getInt8PtrTy())); + TsanVptrLoad = checkSanitizerInterfaceFunction(M.getOrInsertFunction( + "__tsan_vptr_read", Attr, IRB.getVoidTy(), IRB.getInt8PtrTy())); + TsanAtomicThreadFence = checkSanitizerInterfaceFunction(M.getOrInsertFunction( + "__tsan_atomic_thread_fence", Attr, IRB.getVoidTy(), OrdTy)); + TsanAtomicSignalFence = checkSanitizerInterfaceFunction(M.getOrInsertFunction( + "__tsan_atomic_signal_fence", Attr, IRB.getVoidTy(), OrdTy)); + + MemmoveFn = checkSanitizerInterfaceFunction( + M.getOrInsertFunction("memmove", Attr, IRB.getInt8PtrTy(), IRB.getInt8PtrTy(), + IRB.getInt8PtrTy(), IntptrTy)); + MemcpyFn = checkSanitizerInterfaceFunction( + M.getOrInsertFunction("memcpy", Attr, IRB.getInt8PtrTy(), IRB.getInt8PtrTy(), + IRB.getInt8PtrTy(), IntptrTy)); + MemsetFn = checkSanitizerInterfaceFunction( + M.getOrInsertFunction("memset", Attr, IRB.getInt8PtrTy(), IRB.getInt8PtrTy(), + IRB.getInt32Ty(), IntptrTy)); } ThreadSanitizer::ThreadSanitizer(Module &M) { @@ -289,9 +290,7 @@ ThreadSanitizer::ThreadSanitizer(Module &M) { /*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); - }); + [&](Function *Ctor, Function *) { appendToGlobalCtors(M, Ctor, 0); }); } static bool isVtableAccess(Instruction *I) { @@ -559,7 +558,7 @@ bool ThreadSanitizer::instrumentLoadOrStore(Instruction *I, : cast<LoadInst>(I)->getAlignment(); Type *OrigTy = cast<PointerType>(Addr->getType())->getElementType(); const uint32_t TypeSize = DL.getTypeStoreSizeInBits(OrigTy); - FunctionCallee OnAccessFunc = nullptr; + Value *OnAccessFunc = nullptr; if (Alignment == 0 || Alignment >= 8 || (Alignment % (TypeSize / 8)) == 0) OnAccessFunc = IsWrite ? TsanWrite[Idx] : TsanRead[Idx]; else @@ -659,7 +658,7 @@ bool ThreadSanitizer::instrumentAtomic(Instruction *I, const DataLayout &DL) { int Idx = getMemoryAccessFuncIndex(Addr, DL); if (Idx < 0) return false; - FunctionCallee F = TsanAtomicRMW[RMWI->getOperation()][Idx]; + Function *F = TsanAtomicRMW[RMWI->getOperation()][Idx]; if (!F) return false; const unsigned ByteSize = 1U << Idx; @@ -706,9 +705,8 @@ bool ThreadSanitizer::instrumentAtomic(Instruction *I, const DataLayout &DL) { I->eraseFromParent(); } else if (FenceInst *FI = dyn_cast<FenceInst>(I)) { Value *Args[] = {createOrdering(&IRB, FI->getOrdering())}; - FunctionCallee F = FI->getSyncScopeID() == SyncScope::SingleThread - ? TsanAtomicSignalFence - : TsanAtomicThreadFence; + Function *F = FI->getSyncScopeID() == SyncScope::SingleThread ? + TsanAtomicSignalFence : TsanAtomicThreadFence; CallInst *C = CallInst::Create(F, Args); ReplaceInstWithInst(I, C); } |