diff options
Diffstat (limited to 'lib/CodeGen/StackProtector.cpp')
-rw-r--r-- | lib/CodeGen/StackProtector.cpp | 70 |
1 files changed, 18 insertions, 52 deletions
diff --git a/lib/CodeGen/StackProtector.cpp b/lib/CodeGen/StackProtector.cpp index 3b578c7391da..809960c7fdf9 100644 --- a/lib/CodeGen/StackProtector.cpp +++ b/lib/CodeGen/StackProtector.cpp @@ -1,9 +1,8 @@ //===- StackProtector.cpp - Stack Protector Insertion ---------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -18,6 +17,7 @@ #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/Statistic.h" #include "llvm/Analysis/BranchProbabilityInfo.h" +#include "llvm/Analysis/CaptureTracking.h" #include "llvm/Analysis/EHPersonalities.h" #include "llvm/Analysis/OptimizationRemarkEmitter.h" #include "llvm/CodeGen/Passes.h" @@ -157,40 +157,6 @@ bool StackProtector::ContainsProtectableArray(Type *Ty, bool &IsLarge, return NeedsProtector; } -bool StackProtector::HasAddressTaken(const Instruction *AI) { - for (const User *U : AI->users()) { - if (const StoreInst *SI = dyn_cast<StoreInst>(U)) { - if (AI == SI->getValueOperand()) - return true; - } else if (const PtrToIntInst *SI = dyn_cast<PtrToIntInst>(U)) { - if (AI == SI->getOperand(0)) - return true; - } else if (const CallInst *CI = dyn_cast<CallInst>(U)) { - // Ignore intrinsics that are not calls. TODO: Use isLoweredToCall(). - if (!isa<DbgInfoIntrinsic>(CI) && !CI->isLifetimeStartOrEnd()) - return true; - } else if (isa<InvokeInst>(U)) { - return true; - } else if (const SelectInst *SI = dyn_cast<SelectInst>(U)) { - if (HasAddressTaken(SI)) - return true; - } else if (const PHINode *PN = dyn_cast<PHINode>(U)) { - // Keep track of what PHI nodes we have already visited to ensure - // they are only visited once. - if (VisitedPHIs.insert(PN).second) - if (HasAddressTaken(PN)) - return true; - } else if (const GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(U)) { - if (HasAddressTaken(GEP)) - return true; - } else if (const BitCastInst *BI = dyn_cast<BitCastInst>(U)) { - if (HasAddressTaken(BI)) - return true; - } - } - return false; -} - /// Search for the first call to the llvm.stackprotector intrinsic and return it /// if present. static const CallInst *findStackProtectorIntrinsic(Function &F) { @@ -298,7 +264,9 @@ bool StackProtector::RequiresStackProtector() { continue; } - if (Strong && HasAddressTaken(AI)) { + if (Strong && PointerMayBeCaptured(AI, + /* ReturnCaptures */ false, + /* StoreCaptures */ true)) { ++NumAddrTaken; Layout.insert(std::make_pair(AI, MachineFrameInfo::SSPLK_AddrOf)); ORE.emit([&]() { @@ -323,7 +291,7 @@ static Value *getStackGuard(const TargetLoweringBase *TLI, Module *M, IRBuilder<> &B, bool *SupportsSelectionDAGSP = nullptr) { if (Value *Guard = TLI->getIRStackGuard(B)) - return B.CreateLoad(Guard, true, "StackGuard"); + return B.CreateLoad(B.getInt8PtrTy(), Guard, true, "StackGuard"); // Use SelectionDAG SSP handling, since there isn't an IR guard. // @@ -414,15 +382,14 @@ bool StackProtector::InsertStackProtectors() { // Generate epilogue instrumentation. The epilogue intrumentation can be // function-based or inlined depending on which mechanism the target is // providing. - if (Value* GuardCheck = TLI->getSSPStackGuardCheck(*M)) { + 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); - LoadInst *Guard = B.CreateLoad(AI, true, "Guard"); + LoadInst *Guard = B.CreateLoad(B.getInt8PtrTy(), AI, true, "Guard"); CallInst *Call = B.CreateCall(GuardCheck, {Guard}); - llvm::Function *Function = cast<llvm::Function>(GuardCheck); - Call->setAttributes(Function->getAttributes()); - Call->setCallingConv(Function->getCallingConv()); + 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 @@ -474,7 +441,7 @@ bool StackProtector::InsertStackProtectors() { // Generate the stack protector instructions in the old basic block. IRBuilder<> B(BB); Value *Guard = getStackGuard(TLI, M, B); - LoadInst *LI2 = B.CreateLoad(AI, true); + LoadInst *LI2 = B.CreateLoad(B.getInt8PtrTy(), AI, true); Value *Cmp = B.CreateICmpEQ(Guard, LI2); auto SuccessProb = BranchProbabilityInfo::getBranchProbStackProtector(true); @@ -500,14 +467,13 @@ BasicBlock *StackProtector::CreateFailBB() { IRBuilder<> B(FailBB); B.SetCurrentDebugLocation(DebugLoc::get(0, 0, F->getSubprogram())); if (Trip.isOSOpenBSD()) { - Constant *StackChkFail = - M->getOrInsertFunction("__stack_smash_handler", - Type::getVoidTy(Context), - Type::getInt8PtrTy(Context)); + FunctionCallee StackChkFail = M->getOrInsertFunction( + "__stack_smash_handler", Type::getVoidTy(Context), + Type::getInt8PtrTy(Context)); B.CreateCall(StackChkFail, B.CreateGlobalStringPtr(F->getName(), "SSH")); } else { - Constant *StackChkFail = + FunctionCallee StackChkFail = M->getOrInsertFunction("__stack_chk_fail", Type::getVoidTy(Context)); B.CreateCall(StackChkFail, {}); @@ -517,7 +483,7 @@ BasicBlock *StackProtector::CreateFailBB() { } bool StackProtector::shouldEmitSDCheck(const BasicBlock &BB) const { - return HasPrologue && !HasIRCheck && dyn_cast<ReturnInst>(BB.getTerminator()); + return HasPrologue && !HasIRCheck && isa<ReturnInst>(BB.getTerminator()); } void StackProtector::copyToMachineFrameInfo(MachineFrameInfo &MFI) const { |