diff --git a/llvm-build/build.py b/llvm-build/build.py index 11f19925a9dd61ce3a86fd0e70d55f09f70f39cc..830d7ae9dcd0efdac0d441324321fa4ea72c378b 100755 --- a/llvm-build/build.py +++ b/llvm-build/build.py @@ -1678,6 +1678,7 @@ class LlvmLibs(BuildUtils): rt_cflags.append('-fstack-protector-strong') rt_cflags.append('-funwind-tables') rt_cflags.append('-fno-omit-frame-pointer') + rt_cflags.append('-fno-emulated-tls') rt_defines = defines.copy() rt_defines['OHOS'] = '1' diff --git a/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp index b01c74320380231e918010f37475d5667d34be61..69d9f56e8405d5804d5ce3d0b4973dfdfc20c0fd 100644 --- a/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp @@ -90,6 +90,11 @@ static cl::opt ClInstrumentWithCalls( cl::desc("instrument reads and writes with callbacks"), cl::Hidden, cl::init(false)); +static cl::opt ClInstrumentCheckEnabled( + "hwasan-instrument-check-enabled", + cl::desc("instrument reads and writes with callbacks"), cl::Hidden, + cl::init(false)); + static cl::opt ClInstrumentReads("hwasan-instrument-reads", cl::desc("instrument read instructions"), cl::Hidden, cl::init(true)); @@ -827,6 +832,24 @@ void HWAddressSanitizer::instrumentMemAccessOutline(Value *Ptr, bool IsWrite, const int64_t AccessInfo = getAccessInfo(IsWrite, AccessSizeIndex); IRBuilder<> IRB(InsertBefore); Module *M = IRB.GetInsertBlock()->getParent()->getParent(); + + GlobalVariable *HwasanCheckEnabled = NULL; + HwasanCheckEnabled = M->getGlobalVariable("__hwasan_check_enabled"); + if (!HwasanCheckEnabled) { + HwasanCheckEnabled = + new GlobalVariable(*M, Int32Ty, false, GlobalVariable::ExternalLinkage, + nullptr, "__hwasan_check_enabled", nullptr, + GlobalValue::NotThreadLocal, None, true); + } + if (ClInstrumentCheckEnabled && HwasanCheckEnabled) { + Value *CheckEnabled = + IRB.CreateLoad(HwasanCheckEnabled->getValueType(), HwasanCheckEnabled); + Value *cond = IRB.CreateICmpNE(CheckEnabled, IRB.getInt32(0)); + Instruction *CheckCall = + SplitBlockAndInsertIfThen(cond, InsertBefore, false); + IRB.SetInsertPoint(CheckCall); + } + Ptr = IRB.CreateBitCast(Ptr, Int8PtrTy); IRB.CreateCall(Intrinsic::getDeclaration( M, UseShortGranules @@ -841,6 +864,24 @@ void HWAddressSanitizer::instrumentMemAccessInline(Value *Ptr, bool IsWrite, assert(!UsePageAliases); const int64_t AccessInfo = getAccessInfo(IsWrite, AccessSizeIndex); IRBuilder<> IRB(InsertBefore); + Module *M = IRB.GetInsertBlock()->getParent()->getParent(); + + GlobalVariable *HwasanCheckEnabled = NULL; + HwasanCheckEnabled = M->getGlobalVariable("__hwasan_check_enabled"); + if (!HwasanCheckEnabled) { + HwasanCheckEnabled = + new GlobalVariable(*M, Int32Ty, false, GlobalVariable::ExternalLinkage, + nullptr, "__hwasan_check_enabled", nullptr, + GlobalValue::NotThreadLocal, None, true); + } + if (ClInstrumentCheckEnabled && HwasanCheckEnabled) { + Value *CheckEnabled = + IRB.CreateLoad(HwasanCheckEnabled->getValueType(), HwasanCheckEnabled); + Value *cond = IRB.CreateICmpNE(CheckEnabled, IRB.getInt32(0)); + Instruction *CheckCall = + SplitBlockAndInsertIfThen(cond, InsertBefore, false); + IRB.SetInsertPoint(CheckCall); + } Value *PtrLong = IRB.CreatePointerCast(Ptr, IntptrTy); Value *PtrTag = IRB.CreateTrunc(IRB.CreateLShr(PtrLong, PointerTagShift), @@ -929,20 +970,44 @@ bool HWAddressSanitizer::ignoreMemIntrinsic(MemIntrinsic *MI) { void HWAddressSanitizer::instrumentMemIntrinsic(MemIntrinsic *MI) { IRBuilder<> IRB(MI); + + Module *M = IRB.GetInsertBlock()->getParent()->getParent(); + GlobalVariable *HwasanCheckEnabled = NULL; + Instruction *ThenTerm, *ElseTerm; + HwasanCheckEnabled = M->getGlobalVariable("__hwasan_check_enabled"); + if (!HwasanCheckEnabled) { + HwasanCheckEnabled = + new GlobalVariable(*M, Int32Ty, false, GlobalVariable::ExternalLinkage, + nullptr, "__hwasan_check_enabled", nullptr, + GlobalValue::NotThreadLocal, None, true); + } + if (ClInstrumentCheckEnabled && HwasanCheckEnabled) { + Value *CheckEnabled = + IRB.CreateLoad(HwasanCheckEnabled->getValueType(), HwasanCheckEnabled); + Value *cond = IRB.CreateICmpNE(CheckEnabled, IRB.getInt32(0)); + SplitBlockAndInsertIfThenElse(cond, MI, &ThenTerm, &ElseTerm); + } + + IRBuilder<> IRBInstru(ThenTerm); if (isa(MI)) { - IRB.CreateCall( + IRBInstru.CreateCall( isa(MI) ? HWAsanMemmove : HWAsanMemcpy, - {IRB.CreatePointerCast(MI->getOperand(0), IRB.getInt8PtrTy()), - IRB.CreatePointerCast(MI->getOperand(1), IRB.getInt8PtrTy()), - IRB.CreateIntCast(MI->getOperand(2), IntptrTy, false)}); + {IRBInstru.CreatePointerCast(MI->getOperand(0), + IRBInstru.getInt8PtrTy()), + IRBInstru.CreatePointerCast(MI->getOperand(1), + IRBInstru.getInt8PtrTy()), + IRBInstru.CreateIntCast(MI->getOperand(2), IntptrTy, false)}); } else if (isa(MI)) { - IRB.CreateCall( + IRBInstru.CreateCall( HWAsanMemset, - {IRB.CreatePointerCast(MI->getOperand(0), IRB.getInt8PtrTy()), - IRB.CreateIntCast(MI->getOperand(1), IRB.getInt32Ty(), false), - IRB.CreateIntCast(MI->getOperand(2), IntptrTy, false)}); + {IRBInstru.CreatePointerCast(MI->getOperand(0), + IRBInstru.getInt8PtrTy()), + IRBInstru.CreateIntCast(MI->getOperand(1), IRBInstru.getInt32Ty(), + false), + IRBInstru.CreateIntCast(MI->getOperand(2), IntptrTy, false)}); } - MI->eraseFromParent(); + + MI->moveBefore(ElseTerm); } bool HWAddressSanitizer::instrumentMemAccess(InterestingMemoryOperand &O) { @@ -968,6 +1033,23 @@ bool HWAddressSanitizer::instrumentMemAccess(InterestingMemoryOperand &O) { instrumentMemAccessInline(Addr, O.IsWrite, AccessSizeIndex, O.getInsn()); } } else { + GlobalVariable *HwasanCheckEnabled = NULL; + Module *M = IRB.GetInsertBlock()->getParent()->getParent(); + HwasanCheckEnabled = M->getGlobalVariable("__hwasan_check_enabled"); + if (!HwasanCheckEnabled) { + HwasanCheckEnabled = new GlobalVariable( + *M, Int32Ty, false, GlobalVariable::ExternalLinkage, nullptr, + "__hwasan_check_enabled", nullptr, GlobalValue::NotThreadLocal, None, + true); + } + if (ClInstrumentCheckEnabled && HwasanCheckEnabled) { + Value *CheckEnabled = IRB.CreateLoad(HwasanCheckEnabled->getValueType(), + HwasanCheckEnabled); + Value *cond = IRB.CreateICmpNE(CheckEnabled, IRB.getInt32(0)); + Instruction *CheckCall = + SplitBlockAndInsertIfThen(cond, O.getInsn(), false); + IRB.SetInsertPoint(CheckCall); + } IRB.CreateCall(HwasanMemoryAccessCallbackSized[O.IsWrite], {IRB.CreatePointerCast(Addr, IntptrTy), ConstantInt::get(IntptrTy, O.TypeSize / 8)}); @@ -1298,6 +1380,17 @@ bool HWAddressSanitizer::instrumentStack(memtag::StackInfo &SInfo, memtag::AllocaInfo &Info = KV.second; IRBuilder<> IRB(AI->getNextNode()); + Module *M = IRB.GetInsertBlock()->getParent()->getParent(); + + GlobalVariable *HwasanCheckEnabled = NULL; + HwasanCheckEnabled = M->getGlobalVariable("__hwasan_check_enabled"); + if (!HwasanCheckEnabled) { + HwasanCheckEnabled = new GlobalVariable( + *M, Int32Ty, false, GlobalVariable::ExternalLinkage, nullptr, + "__hwasan_check_enabled", nullptr, GlobalValue::NotThreadLocal, None, + true); + } + // Replace uses of the alloca with tagged address. Value *Tag = getAllocaTag(IRB, StackTag, AI, N); Value *AILong = IRB.CreatePointerCast(AI, IntptrTy); @@ -1347,6 +1440,15 @@ bool HWAddressSanitizer::instrumentStack(memtag::StackInfo &SInfo, auto TagEnd = [&](Instruction *Node) { IRB.SetInsertPoint(Node); + + if (ClInstrumentCheckEnabled && HwasanCheckEnabled) { + Value *CheckEnabled = IRB.CreateLoad(HwasanCheckEnabled->getValueType(), + HwasanCheckEnabled); + Value *cond = IRB.CreateICmpNE(CheckEnabled, IRB.getInt32(0)); + Instruction *CheckCall = SplitBlockAndInsertIfThen(cond, Node, false); + IRB.SetInsertPoint(CheckCall); + } + Value *UARTag = getUARTag(IRB, StackTag); // When untagging, use the `AlignedSize` because we need to set the tags // for the entire alloca to zero. If we used `Size` here, we would @@ -1366,6 +1468,14 @@ bool HWAddressSanitizer::instrumentStack(memtag::StackInfo &SInfo, if (DetectUseAfterScope && StandardLifetime) { IntrinsicInst *Start = Info.LifetimeStart[0]; IRB.SetInsertPoint(Start->getNextNode()); + if (ClInstrumentCheckEnabled && HwasanCheckEnabled) { + Value *CheckEnabled = IRB.CreateLoad(HwasanCheckEnabled->getValueType(), + HwasanCheckEnabled); + Value *cond = IRB.CreateICmpNE(CheckEnabled, IRB.getInt32(0)); + Instruction *CheckCall = + SplitBlockAndInsertIfThen(cond, Start->getNextNode(), false); + IRB.SetInsertPoint(CheckCall); + } tagAlloca(IRB, AI, Tag, Size); if (!memtag::forAllReachableExits(DT, PDT, LI, Start, Info.LifetimeEnd, SInfo.RetVec, TagEnd)) { @@ -1373,6 +1483,15 @@ bool HWAddressSanitizer::instrumentStack(memtag::StackInfo &SInfo, End->eraseFromParent(); } } else { + if (ClInstrumentCheckEnabled && HwasanCheckEnabled) { + Value *CheckEnabled = IRB.CreateLoad(HwasanCheckEnabled->getValueType(), + HwasanCheckEnabled); + Value *cond = IRB.CreateICmpNE(CheckEnabled, IRB.getInt32(0)); + Instruction *InsertPt = cast(cond); + Instruction *CheckCall = + SplitBlockAndInsertIfThen(cond, InsertPt->getNextNode(), false); + IRB.SetInsertPoint(CheckCall); + } tagAlloca(IRB, AI, Tag, Size); for (auto *RI : SInfo.RetVec) TagEnd(RI); @@ -1464,6 +1583,24 @@ bool HWAddressSanitizer::sanitizeFunction(Function &F, Instruction *InsertPt = &*F.getEntryBlock().begin(); IRBuilder<> EntryIRB(InsertPt); + + Module *M = EntryIRB.GetInsertBlock()->getParent()->getParent(); + GlobalVariable *HwasanCheckEnabled = NULL; + HwasanCheckEnabled = M->getGlobalVariable("__hwasan_check_enabled"); + if (!HwasanCheckEnabled) { + HwasanCheckEnabled = + new GlobalVariable(*M, Int32Ty, false, GlobalVariable::ExternalLinkage, + nullptr, "__hwasan_check_enabled", nullptr, + GlobalValue::NotThreadLocal, None, true); + } + if (ClInstrumentCheckEnabled && HwasanCheckEnabled) { + Value *CheckEnabled = EntryIRB.CreateLoad( + HwasanCheckEnabled->getValueType(), HwasanCheckEnabled); + Value *cond = EntryIRB.CreateICmpNE(CheckEnabled, EntryIRB.getInt32(0)); + Instruction *CheckCall = SplitBlockAndInsertIfThen(cond, InsertPt, false); + EntryIRB.SetInsertPoint(CheckCall); + } + emitPrologue(EntryIRB, /*WithFrameRecord*/ ClRecordStackHistory != none && Mapping.WithFrameRecord &&