Index: lib/Transforms/Instrumentation/AddressSanitizer.cpp =================================================================== --- lib/Transforms/Instrumentation/AddressSanitizer.cpp +++ lib/Transforms/Instrumentation/AddressSanitizer.cpp @@ -443,7 +443,8 @@ Value *ShadowValue, uint32_t TypeSize); Instruction *generateCrashCode(Instruction *InsertBefore, Value *Addr, bool IsWrite, size_t AccessSizeIndex, - Value *SizeArgument, uint32_t Exp); + Value *SizeArgument, uint32_t Exp, + Value *SourceLoc); void instrumentMemIntrinsic(MemIntrinsic *MI); Value *memToShadow(Value *Shadow, IRBuilder<> &IRB); bool runOnFunction(Function &F) override; @@ -777,15 +778,16 @@ } /// \brief Create a global describing a source location. -static GlobalVariable *createPrivateGlobalForSourceLoc(Module &M, - LocationMetadata MD) { +static GlobalVariable *createGlobalForSourceLoc(Module &M, + LocationMetadata MD, + bool isPrivate) { Constant *LocData[] = { createPrivateGlobalForString(M, MD.Filename, true), ConstantInt::get(Type::getInt32Ty(M.getContext()), MD.LineNo), ConstantInt::get(Type::getInt32Ty(M.getContext()), MD.ColumnNo), }; auto LocStruct = ConstantStruct::getAnon(LocData); - auto GV = new GlobalVariable(M, LocStruct->getType(), true, + auto GV = new GlobalVariable(M, LocStruct->getType(), isPrivate, GlobalValue::PrivateLinkage, LocStruct, kAsanGenPrefix); GV->setUnnamedAddr(true); @@ -997,21 +999,30 @@ Value *Addr, bool IsWrite, size_t AccessSizeIndex, Value *SizeArgument, - uint32_t Exp) { + uint32_t Exp, + Value *SourceLoc) { IRBuilder<> IRB(InsertBefore); Value *ExpVal = Exp == 0 ? nullptr : ConstantInt::get(IRB.getInt32Ty(), Exp); CallInst *Call = nullptr; if (SizeArgument) { if (Exp == 0) - Call = IRB.CreateCall(AsanErrorCallbackSized[IsWrite][0], - {Addr, SizeArgument}); + if (Recover) + Call = IRB.CreateCall(AsanErrorCallbackSized[IsWrite][0], + {Addr, SizeArgument, SourceLoc}); + else + Call = IRB.CreateCall(AsanErrorCallbackSized[IsWrite][0], + {Addr, SizeArgument}); else Call = IRB.CreateCall(AsanErrorCallbackSized[IsWrite][1], {Addr, SizeArgument, ExpVal}); } else { if (Exp == 0) - Call = - IRB.CreateCall(AsanErrorCallback[IsWrite][0][AccessSizeIndex], Addr); + if (Recover) + Call = IRB.CreateCall(AsanErrorCallback[IsWrite][0][AccessSizeIndex], + {Addr, SourceLoc}); + else + Call = IRB.CreateCall(AsanErrorCallback[IsWrite][0][AccessSizeIndex], + {Addr}); else Call = IRB.CreateCall(AsanErrorCallback[IsWrite][1][AccessSizeIndex], {Addr, ExpVal}); @@ -1051,10 +1062,23 @@ Value *AddrLong = IRB.CreatePointerCast(Addr, IntptrTy); size_t AccessSizeIndex = TypeSizeToSizeIndex(TypeSize); + Value *SourceLoc = nullptr; + if (Recover) { + Function *F = OrigIns->getParent()->getParent(); + Module *M = F->getParent(); + GlobalVariable *SourceLocDescr = + createGlobalForSourceLoc(*M, LocationMetadata(), false); + SourceLoc = IRB.CreatePointerCast(SourceLocDescr, IntptrTy); + } + if (UseCalls) { if (Exp == 0) - IRB.CreateCall(AsanMemoryAccessCallback[IsWrite][0][AccessSizeIndex], - AddrLong); + if (Recover) + IRB.CreateCall(AsanMemoryAccessCallback[IsWrite][0][AccessSizeIndex], + {AddrLong, SourceLoc}); + else + IRB.CreateCall(AsanMemoryAccessCallback[IsWrite][0][AccessSizeIndex], + AddrLong); else IRB.CreateCall(AsanMemoryAccessCallback[IsWrite][1][AccessSizeIndex], {AddrLong, ConstantInt::get(IRB.getInt32Ty(), Exp)}); @@ -1095,8 +1119,9 @@ CrashTerm = SplitBlockAndInsertIfThen(Cmp, InsertBefore, !Recover); } - Instruction *Crash = generateCrashCode(CrashTerm, AddrLong, IsWrite, - AccessSizeIndex, SizeArgument, Exp); + Instruction *Crash = + generateCrashCode(CrashTerm, AddrLong, IsWrite, AccessSizeIndex, + SizeArgument, Exp, SourceLoc); Crash->setDebugLoc(OrigIns->getDebugLoc()); } @@ -1357,7 +1382,7 @@ Constant *SourceLoc; if (!MD.SourceLoc.empty()) { - auto SourceLocGlobal = createPrivateGlobalForSourceLoc(M, MD.SourceLoc); + auto SourceLocGlobal = createGlobalForSourceLoc(M, MD.SourceLoc, true); SourceLoc = ConstantExpr::getPointerCast(SourceLocGlobal, IntptrTy); } else { SourceLoc = ConstantInt::get(IntptrTy, 0); @@ -1427,6 +1452,8 @@ void AddressSanitizer::initializeCallbacks(Module &M) { IRBuilder<> IRB(*C); + assert (!(Exp && Recover) && "ASan doesn't support experiments in recover " + "mode!"); // Create __asan_report* callbacks. // IsWrite, TypeSize and Exp are encoded in the function name. for (int Exp = 0; Exp < 2; Exp++) { @@ -1435,26 +1462,30 @@ const std::string ExpStr = Exp ? "exp_" : ""; const std::string SuffixStr = CompileKernel ? "N" : "_n"; const std::string EndingStr = Recover ? "_noabort" : ""; - Type *ExpType = Exp ? Type::getInt32Ty(*C) : nullptr; + Type *OptType = nullptr; + if (Exp) + OptType = Type::getInt32Ty(*C); + else if (Recover) + OptType = IntptrTy; AsanErrorCallbackSized[AccessIsWrite][Exp] = checkSanitizerInterfaceFunction(M.getOrInsertFunction( kAsanReportErrorTemplate + ExpStr + TypeStr + SuffixStr + EndingStr, - IRB.getVoidTy(), IntptrTy, IntptrTy, ExpType, nullptr)); + IRB.getVoidTy(), IntptrTy, IntptrTy, OptType, nullptr)); AsanMemoryAccessCallbackSized[AccessIsWrite][Exp] = checkSanitizerInterfaceFunction(M.getOrInsertFunction( ClMemoryAccessCallbackPrefix + ExpStr + TypeStr + "N" + EndingStr, - IRB.getVoidTy(), IntptrTy, IntptrTy, ExpType, nullptr)); + IRB.getVoidTy(), IntptrTy, IntptrTy, OptType, nullptr)); for (size_t AccessSizeIndex = 0; AccessSizeIndex < kNumberOfAccessSizes; AccessSizeIndex++) { const std::string Suffix = TypeStr + itostr(1 << AccessSizeIndex); AsanErrorCallback[AccessIsWrite][Exp][AccessSizeIndex] = checkSanitizerInterfaceFunction(M.getOrInsertFunction( kAsanReportErrorTemplate + ExpStr + Suffix + EndingStr, - IRB.getVoidTy(), IntptrTy, ExpType, nullptr)); + IRB.getVoidTy(), IntptrTy, OptType, nullptr)); AsanMemoryAccessCallback[AccessIsWrite][Exp][AccessSizeIndex] = checkSanitizerInterfaceFunction(M.getOrInsertFunction( ClMemoryAccessCallbackPrefix + ExpStr + Suffix + EndingStr, - IRB.getVoidTy(), IntptrTy, ExpType, nullptr)); + IRB.getVoidTy(), IntptrTy, OptType, nullptr)); } } }