diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2021-06-13 19:31:46 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2021-07-31 18:56:55 +0000 |
| commit | af732203b8f7f006927528db5497f5cbc4c4742a (patch) | |
| tree | 596f112de3b76118552871dbb6114bb7e3e17f40 /contrib/llvm-project/llvm/lib/CodeGen/StackProtector.cpp | |
| parent | 83dea422ac8d4a8323e64203c2eadaa813768717 (diff) | |
Diffstat (limited to 'contrib/llvm-project/llvm/lib/CodeGen/StackProtector.cpp')
| -rw-r--r-- | contrib/llvm-project/llvm/lib/CodeGen/StackProtector.cpp | 48 |
1 files changed, 33 insertions, 15 deletions
diff --git a/contrib/llvm-project/llvm/lib/CodeGen/StackProtector.cpp b/contrib/llvm-project/llvm/lib/CodeGen/StackProtector.cpp index a343791807e6..10c6dcbdb049 100644 --- a/contrib/llvm-project/llvm/lib/CodeGen/StackProtector.cpp +++ b/contrib/llvm-project/llvm/lib/CodeGen/StackProtector.cpp @@ -170,7 +170,8 @@ bool StackProtector::HasAddressTaken(const Instruction *AI, // If this instruction accesses memory make sure it doesn't access beyond // the bounds of the allocated object. Optional<MemoryLocation> MemLoc = MemoryLocation::getOrNone(I); - if (MemLoc.hasValue() && MemLoc->Size.getValue() > AllocSize) + if (MemLoc.hasValue() && MemLoc->Size.hasValue() && + MemLoc->Size.getValue() > AllocSize) return true; switch (I->getOpcode()) { case Instruction::Store: @@ -191,7 +192,7 @@ bool StackProtector::HasAddressTaken(const Instruction *AI, // Ignore intrinsics that do not become real instructions. // TODO: Narrow this to intrinsics that have store-like effects. const auto *CI = cast<CallInst>(I); - if (!isa<DbgInfoIntrinsic>(CI) && !CI->isLifetimeStartOrEnd()) + if (!CI->isDebugOrPseudoInst() && !CI->isLifetimeStartOrEnd()) return true; break; } @@ -251,10 +252,9 @@ bool StackProtector::HasAddressTaken(const Instruction *AI, static const CallInst *findStackProtectorIntrinsic(Function &F) { for (const BasicBlock &BB : F) for (const Instruction &I : BB) - if (const CallInst *CI = dyn_cast<CallInst>(&I)) - if (CI->getCalledFunction() == - Intrinsic::getDeclaration(F.getParent(), Intrinsic::stackprotector)) - return CI; + if (const auto *II = dyn_cast<IntrinsicInst>(&I)) + if (II->getIntrinsicID() == Intrinsic::stackprotector) + return II; return nullptr; } @@ -274,7 +274,6 @@ static const CallInst *findStackProtectorIntrinsic(Function &F) { bool StackProtector::RequiresStackProtector() { bool Strong = false; bool NeedsProtector = false; - HasPrologue = findStackProtectorIntrinsic(*F); if (F->hasFnAttribute(Attribute::SafeStack)) return false; @@ -295,8 +294,6 @@ bool StackProtector::RequiresStackProtector() { Strong = true; // Use the same heuristic as strong to determine SSPLayout } else if (F->hasFnAttribute(Attribute::StackProtectStrong)) Strong = true; - else if (HasPrologue) - NeedsProtector = true; else if (!F->hasFnAttribute(Attribute::StackProtect)) return false; @@ -381,7 +378,10 @@ bool StackProtector::RequiresStackProtector() { static Value *getStackGuard(const TargetLoweringBase *TLI, Module *M, IRBuilder<> &B, bool *SupportsSelectionDAGSP = nullptr) { - if (Value *Guard = TLI->getIRStackGuard(B)) + Value *Guard = TLI->getIRStackGuard(B); + auto GuardMode = TLI->getTargetMachine().Options.StackProtectorGuard; + if ((GuardMode == llvm::StackProtectorGuards::TLS || + GuardMode == llvm::StackProtectorGuards::None) && Guard) return B.CreateLoad(B.getInt8PtrTy(), Guard, true, "StackGuard"); // Use SelectionDAG SSP handling, since there isn't an IR guard. @@ -470,21 +470,36 @@ bool StackProtector::InsertStackProtectors() { // instrumentation has already been generated. HasIRCheck = true; + // If we're instrumenting a block with a musttail call, the check has to be + // inserted before the call rather than between it and the return. The + // verifier guarantees that a musttail call is either directly before the + // return or with a single correct bitcast of the return value in between so + // we don't need to worry about many situations here. + Instruction *CheckLoc = RI; + Instruction *Prev = RI->getPrevNonDebugInstruction(); + if (Prev && isa<CallInst>(Prev) && cast<CallInst>(Prev)->isMustTailCall()) + CheckLoc = Prev; + else if (Prev) { + Prev = Prev->getPrevNonDebugInstruction(); + if (Prev && isa<CallInst>(Prev) && cast<CallInst>(Prev)->isMustTailCall()) + CheckLoc = Prev; + } + // Generate epilogue instrumentation. The epilogue intrumentation can be // function-based or inlined depending on which mechanism the target is // providing. if (Function *GuardCheck = TLI->getSSPStackGuardCheck(*M)) { // Generate the function-based epilogue instrumentation. // The target provides a guard check function, generate a call to it. - IRBuilder<> B(RI); + IRBuilder<> B(CheckLoc); LoadInst *Guard = B.CreateLoad(B.getInt8PtrTy(), AI, true, "Guard"); CallInst *Call = B.CreateCall(GuardCheck, {Guard}); Call->setAttributes(GuardCheck->getAttributes()); Call->setCallingConv(GuardCheck->getCallingConv()); } else { // Generate the epilogue with inline instrumentation. - // If we do not support SelectionDAG based tail calls, generate IR level - // tail calls. + // If we do not support SelectionDAG based calls, generate IR level + // calls. // // For each block with a return instruction, convert this: // @@ -514,7 +529,8 @@ bool StackProtector::InsertStackProtectors() { BasicBlock *FailBB = CreateFailBB(); // Split the basic block before the return instruction. - BasicBlock *NewBB = BB->splitBasicBlock(RI->getIterator(), "SP_return"); + BasicBlock *NewBB = + BB->splitBasicBlock(CheckLoc->getIterator(), "SP_return"); // Update the dominator tree if we need to. if (DT && DT->isReachableFromEntry(BB)) { @@ -556,7 +572,9 @@ BasicBlock *StackProtector::CreateFailBB() { LLVMContext &Context = F->getContext(); BasicBlock *FailBB = BasicBlock::Create(Context, "CallStackCheckFailBlk", F); IRBuilder<> B(FailBB); - B.SetCurrentDebugLocation(DebugLoc::get(0, 0, F->getSubprogram())); + if (F->getSubprogram()) + B.SetCurrentDebugLocation( + DILocation::get(Context, 0, 0, F->getSubprogram())); if (Trip.isOSOpenBSD()) { FunctionCallee StackChkFail = M->getOrInsertFunction( "__stack_smash_handler", Type::getVoidTy(Context), |
